From 05d7c281280e2975a7c49bc26e5b2a79230efca3 Mon Sep 17 00:00:00 2001 From: JB Date: Mon, 15 Dec 2025 15:41:41 -0800 Subject: [PATCH] feat: Expand debug TTS samples with additional cases and implement validation test for minimum sample counts --- abogen/debug_tts_samples.py | 220 ++++++++++++++++++- abogen/web/templates/settings.html | 14 +- tests/fixtures/abogen_debug_tts_samples.epub | Bin 2048 -> 3461 bytes tests/test_debug_tts_samples.py | 24 ++ 4 files changed, 246 insertions(+), 12 deletions(-) diff --git a/abogen/debug_tts_samples.py b/abogen/debug_tts_samples.py index 8c0d44c..b5490d4 100644 --- a/abogen/debug_tts_samples.py +++ b/abogen/debug_tts_samples.py @@ -21,54 +21,254 @@ class DebugTTSSample: DEBUG_TTS_SAMPLES: Sequence[DebugTTSSample] = ( DebugTTSSample( code="APOS_001", - label="Apostrophes & contractions", + label="Apostrophes & contractions (1)", text="It's a beautiful day, isn't it? Let's see what we'll do.", ), + DebugTTSSample( + code="APOS_002", + label="Apostrophes & contractions (2)", + text="I'm sure you're ready; we'd better go before it's too late.", + ), + DebugTTSSample( + code="APOS_003", + label="Apostrophes & contractions (3)", + text="He'll say it's fine, but I can't promise it'll work.", + ), + DebugTTSSample( + code="APOS_004", + label="Apostrophes & contractions (4)", + text="They've done it, and I'd agree they've earned it.", + ), + DebugTTSSample( + code="APOS_005", + label="Apostrophes & contractions (5)", + text="She's here, we're late, they're waiting, and you're right.", + ), DebugTTSSample( code="POS_001", - label="Plural possessives", + label="Plural possessives (1)", text="The dogs' bowls were empty, but the boss's office was quiet.", ), + DebugTTSSample( + code="POS_002", + label="Plural possessives (2)", + text="The teachers' lounge was closed during the students' exams.", + ), + DebugTTSSample( + code="POS_003", + label="Plural possessives (3)", + text="The actresses' roles changed, and the directors' notes piled up.", + ), + DebugTTSSample( + code="POS_004", + label="Plural possessives (4)", + text="The Joneses' car was parked by the neighbors' fence.", + ), + DebugTTSSample( + code="POS_005", + label="Plural possessives (5)", + text="The bosses' meeting ended before the witnesses' statements began.", + ), DebugTTSSample( code="NUM_001", - label="Grouped numbers", + label="Grouped numbers (1)", text="There are 1,234 apples, 56 oranges, and 7.89 liters of juice.", ), + DebugTTSSample( + code="NUM_002", + label="Grouped numbers (2)", + text="The population is 10,000,000 and the area is 123.45 square miles.", + ), + DebugTTSSample( + code="NUM_003", + label="Grouped numbers (3)", + text="Set the timer for 0.5 seconds, then wait 2.0 minutes.", + ), + DebugTTSSample( + code="NUM_004", + label="Grouped numbers (4)", + text="We measured 3.1415 radians and wrote down 2,718.28 as well.", + ), + DebugTTSSample( + code="NUM_005", + label="Grouped numbers (5)", + text="The sequence is 1, 2, 3, 4, 5, and then 13.", + ), DebugTTSSample( code="YEAR_001", - label="Years and decades", + label="Years and decades (1)", text="In 1999, people said the '90s were over.", ), + DebugTTSSample( + code="YEAR_002", + label="Years and decades (2)", + text="In 2001, the show premiered; by 2010 it was everywhere.", + ), + DebugTTSSample( + code="YEAR_003", + label="Years and decades (3)", + text="The 1980s were loud, and the 1970s were groovy.", + ), + DebugTTSSample( + code="YEAR_004", + label="Years and decades (4)", + text="She loved the '80s, but he preferred the '60s.", + ), + DebugTTSSample( + code="YEAR_005", + label="Years and decades (5)", + text="In 2024, we looked back at 2020 and planned for 2030.", + ), DebugTTSSample( code="DATE_001", - label="ISO dates", + label="Dates (1)", text="On 2023-01-01, we celebrated the new year.", ), + DebugTTSSample( + code="DATE_002", + label="Dates (2)", + text="The deadline is 1999-12-31 at midnight.", + ), + DebugTTSSample( + code="DATE_003", + label="Dates (3)", + text="Leap day happens on 2024-02-29.", + ), + DebugTTSSample( + code="DATE_004", + label="Dates (4)", + text="Some formats look like 01/02/2003 and can be ambiguous.", + ), + DebugTTSSample( + code="DATE_005", + label="Dates (5)", + text="We met on March 5, 2020 and again on Apr. 7, 2021.", + ), DebugTTSSample( code="CUR_001", - label="Currency symbols", + label="Currency symbols (1)", text="The price is $10.50, but it was £8.00 yesterday.", ), + DebugTTSSample( + code="CUR_002", + label="Currency symbols (2)", + text="Tickets cost €12, and the fine was $0.99.", + ), + DebugTTSSample( + code="CUR_003", + label="Currency symbols (3)", + text="The bill was ¥500 and the refund was $-3.25.", + ), + DebugTTSSample( + code="CUR_004", + label="Currency symbols (4)", + text="He paid £1,234.56 for the instrument.", + ), + DebugTTSSample( + code="CUR_005", + label="Currency symbols (5)", + text="The subscription is $5 per month, or $50 per year.", + ), DebugTTSSample( code="TITLE_001", - label="Titles and abbreviations", + label="Titles and abbreviations (1)", text="Dr. Smith lives on Elm St. near the U.S. border.", ), + DebugTTSSample( + code="TITLE_002", + label="Titles and abbreviations (2)", + text="Mr. and Mrs. Doe met Prof. Adams at 5 p.m.", + ), + DebugTTSSample( + code="TITLE_003", + label="Titles and abbreviations (3)", + text="Gen. Lee spoke to Sgt. Rivera on Main St.", + ), + DebugTTSSample( + code="TITLE_004", + label="Titles and abbreviations (4)", + text="The report came from the U.K. office, not the U.S.A. team.", + ), + DebugTTSSample( + code="TITLE_005", + label="Titles and abbreviations (5)", + text="St. John's is different from St. Louis.", + ), DebugTTSSample( code="PUNC_001", - label="Terminal punctuation", + label="Terminal punctuation (1)", text="This sentence ends without punctuation", ), + DebugTTSSample( + code="PUNC_002", + label="Terminal punctuation (2)", + text="An ellipsis is already present...", + ), + DebugTTSSample( + code="PUNC_003", + label="Terminal punctuation (3)", + text="A question without a mark", + ), + DebugTTSSample( + code="PUNC_004", + label="Terminal punctuation (4)", + text="An exclamation without a bang", + ), + DebugTTSSample( + code="PUNC_005", + label="Terminal punctuation (5)", + text='A quote ends here"', + ), DebugTTSSample( code="QUOTE_001", - label="ALL CAPS inside quotes", + label="ALL CAPS inside quotes (1)", text='He shouted, "THIS IS IMPORTANT!" and then whispered, "ok."', ), + DebugTTSSample( + code="QUOTE_002", + label="ALL CAPS inside quotes (2)", + text='She said, "NO WAY", but he replied, "maybe".', + ), + DebugTTSSample( + code="QUOTE_003", + label="ALL CAPS inside quotes (3)", + text='The sign read "DO NOT ENTER" and the note read "pls knock".', + ), + DebugTTSSample( + code="QUOTE_004", + label="ALL CAPS inside quotes (4)", + text='He muttered, "OK", then yelled, "STOP!"', + ), + DebugTTSSample( + code="QUOTE_005", + label="ALL CAPS inside quotes (5)", + text='They chanted, "USA!" and someone wrote "idk".', + ), DebugTTSSample( code="FOOT_001", - label="Footnote indicators", + label="Footnote indicators (1)", text="This is a sentence with a footnote[1] and another[12].", ), + DebugTTSSample( + code="FOOT_002", + label="Footnote indicators (2)", + text="Some books use multiple footnotes like this[2][3] in a row.", + ), + DebugTTSSample( + code="FOOT_003", + label="Footnote indicators (3)", + text="A footnote can appear mid-sentence[4] and continue afterward.", + ), + DebugTTSSample( + code="FOOT_004", + label="Footnote indicators (4)", + text="Edge cases include [0] or very large indices like [1234].", + ), + DebugTTSSample( + code="FOOT_005", + label="Footnote indicators (5)", + text="Sometimes a footnote follows punctuation.[5] Sometimes it doesn't[6]", + ), ) diff --git a/abogen/web/templates/settings.html b/abogen/web/templates/settings.html index 44fe35e..30c4977 100644 --- a/abogen/web/templates/settings.html +++ b/abogen/web/templates/settings.html @@ -11,6 +11,14 @@
Settings saved successfully.
{% endif %} + {% with messages = get_flashed_messages(with_categories=True) %} + {% if messages %} + {% for category, message in messages %} +
{{ message }}
+ {% endfor %} + {% endif %} + {% endwith %} +
+ +
{% endblock %} diff --git a/tests/fixtures/abogen_debug_tts_samples.epub b/tests/fixtures/abogen_debug_tts_samples.epub index f07f3927cc1573bed33bee930e70007cf81e6f5e..6e78488fa63cd45b31b05e48d069215988d92b83 100644 GIT binary patch delta 2321 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 X6>O704IBcV1(RM4AqKMs00000%!QiK diff --git a/tests/test_debug_tts_samples.py b/tests/test_debug_tts_samples.py index c55b08f..aaa6c24 100644 --- a/tests/test_debug_tts_samples.py +++ b/tests/test_debug_tts_samples.py @@ -95,3 +95,27 @@ def test_settings_debug_route_writes_manifest(tmp_path, monkeypatch): filenames = {item["filename"] for item in manifest.get("artifacts", [])} assert "overall.wav" in filenames assert any(name.startswith("case_") and name.endswith(".wav") for name in filenames) + + +def test_debug_samples_have_minimum_per_category(): + prefixes = { + "APOS": 5, + "POS": 5, + "NUM": 5, + "YEAR": 5, + "DATE": 5, + "CUR": 5, + "TITLE": 5, + "PUNC": 5, + "QUOTE": 5, + "FOOT": 5, + } + + counts = {prefix: 0 for prefix in prefixes} + for sample in DEBUG_TTS_SAMPLES: + prefix = sample.code.split("_", 1)[0] + if prefix in counts: + counts[prefix] += 1 + + for prefix, minimum in prefixes.items(): + assert counts[prefix] >= minimum