"""Тесты склейки сегментов диаризации в реплики и нарезки длинных кусков.""" from app.turns import Segment, chunk_ranges, merge_turns, speech_stats def seg(start, end, speaker): return Segment(start=start, end=end, speaker=speaker) class TestMergeTurns: def test_merges_adjacent_segments_of_same_speaker(self): turns = merge_turns([seg(0, 2, 0), seg(2.3, 4, 0)], gap=0.8) assert len(turns) == 1 assert turns[0].start == 0 and turns[0].end == 4 def test_keeps_separate_when_gap_is_large(self): turns = merge_turns([seg(0, 2, 0), seg(5, 6, 0)], gap=0.8) assert len(turns) == 2 def test_never_merges_different_speakers(self): turns = merge_turns([seg(0, 2, 0), seg(2.1, 4, 1)], gap=0.8) assert len(turns) == 2 assert [t.speaker for t in turns] == [0, 1] def test_empty_input(self): assert merge_turns([], gap=0.8) == [] def test_preserves_order(self): turns = merge_turns([seg(0, 1, 0), seg(2, 3, 1), seg(4, 5, 0)], gap=0.5) assert [t.start for t in turns] == [0, 2, 4] class TestChunkRanges: def test_short_turn_is_single_chunk(self): assert chunk_ranges(10.0, 20.0, max_len=150) == [(10.0, 20.0)] def test_long_turn_is_split(self): chunks = chunk_ranges(0.0, 400.0, max_len=150) assert len(chunks) == 3 assert chunks[0] == (0.0, 150.0) assert chunks[-1][1] == 400.0 def test_chunks_are_contiguous(self): chunks = chunk_ranges(5.0, 500.0, max_len=150) for a, b in zip(chunks, chunks[1:]): assert a[1] == b[0] def test_no_chunk_exceeds_limit(self): """Главное требование: GigaAM падает на кусках длиннее 200 секунд.""" for a, b in chunk_ranges(0.0, 1000.0, max_len=150): assert b - a <= 150 def test_exact_boundary_is_not_split(self): assert chunk_ranges(0.0, 150.0, max_len=150) == [(0.0, 150.0)] class TestSpeechStats: def test_counts_share_per_speaker(self): stats = speech_stats([seg(0, 30, 0), seg(30, 10 + 60, 1)]) assert stats["speakers"] == 2 def test_total_speech_time(self): stats = speech_stats([seg(0, 10, 0), seg(20, 30, 1)]) assert stats["speech_sec"] == 20 def test_share_sums_to_one_hundred(self): stats = speech_stats([seg(0, 25, 0), seg(25, 100, 1)]) total = sum(s["share_pct"] for s in stats["by_speaker"]) assert round(total) == 100 def test_empty_segments(self): stats = speech_stats([]) assert stats["speakers"] == 0 assert stats["speech_sec"] == 0