from abogen.speaker_analysis import analyze_speakers def _chapters(): return [ { "id": "0001", "index": 0, "title": "Test", "text": "", "enabled": True, } ] def _chunk(text: str, idx: int) -> dict: return { "id": f"chunk-{idx}", "chapter_index": 0, "chunk_index": idx, "text": text, } def test_analyze_speakers_infers_gender_from_pronouns(): chunks = [ _chunk('"Greetings," said John. He adjusted his hat as he smiled.', 0), _chunk( '"Hello," said Mary. She straightened her dress as she introduced herself.', 1, ), _chunk('"Nice to meet you," said Alex.', 2), ] analysis = analyze_speakers(_chapters(), chunks, threshold=1, max_speakers=0) john = analysis.speakers.get("john") mary = analysis.speakers.get("mary") alex = analysis.speakers.get("alex") assert john is not None assert mary is not None assert alex is not None assert john.gender == "male" assert mary.gender == "female" assert alex.gender == "unknown" def test_analyze_speakers_ignores_leading_stopwords(): chunks = [ _chunk('But Volescu said, "We march at dawn."', 0), _chunk('Then Blue Leader shouted, "Hold the perimeter."', 1), ] analysis = analyze_speakers(_chapters(), chunks, threshold=1, max_speakers=0) speakers = analysis.speakers assert "volescu" in speakers assert speakers["volescu"].label == "Volescu" assert "blue_leader" in speakers assert speakers["blue_leader"].label == "Blue Leader" assert "but_volescu" not in speakers assert "then_blue_leader" not in speakers def test_analyze_speakers_applies_threshold_suppression(): chunks = [ _chunk('"Hello there," said Narrator.', 0), _chunk('"It is lying," said Green.', 1), ] analysis = analyze_speakers(_chapters(), chunks, threshold=3, max_speakers=0) green = analysis.speakers.get("green") assert green is not None assert green.suppressed is True assert "green" in analysis.suppressed def test_sample_excerpt_includes_context_paragraphs(): chunks = [ _chunk("The hallway was quiet as footsteps approached.", 0), _chunk('"Open the door," said John as he reached for the handle.', 1), _chunk("Mary watched him closely, unsure of his intent.", 2), ] analysis = analyze_speakers(_chapters(), chunks, threshold=1, max_speakers=0) john = analysis.speakers.get("john") assert john is not None assert john.sample_quotes, "Expected John to have at least one sample quote" excerpt = john.sample_quotes[0]["excerpt"] assert "The hallway was quiet" in excerpt assert '"Open the door," said John' in excerpt assert "Mary watched him closely" in excerpt