aboutsummaryrefslogtreecommitdiff
path: root/working/meeting-transcription-service/tests/test_diarize.py
diff options
context:
space:
mode:
Diffstat (limited to 'working/meeting-transcription-service/tests/test_diarize.py')
-rw-r--r--working/meeting-transcription-service/tests/test_diarize.py74
1 files changed, 74 insertions, 0 deletions
diff --git a/working/meeting-transcription-service/tests/test_diarize.py b/working/meeting-transcription-service/tests/test_diarize.py
new file mode 100644
index 0000000..ef009b8
--- /dev/null
+++ b/working/meeting-transcription-service/tests/test_diarize.py
@@ -0,0 +1,74 @@
+"""Tests for diarize's pure parts. The pyannote pipeline itself is not loaded here."""
+
+import sys
+from collections import namedtuple
+from pathlib import Path
+
+import pytest
+
+sys.path.insert(0, str(Path(__file__).resolve().parent.parent / "src"))
+
+import diarize # noqa: E402
+
+Segment = namedtuple("Segment", "start end")
+
+
+class TestTurnsFromTracks:
+ def test_diarize_turns_from_tracks_converts_and_sorts(self):
+ """Normal: (segment, track, label) triples become sorted turn dicts."""
+ tracks = [(Segment(5.0, 9.25), "_", "SPEAKER_01"), (Segment(0.5, 4.0), "_", "SPEAKER_00")]
+ assert diarize.turns_from_tracks(tracks) == [
+ {"start": 0.5, "end": 4.0, "speaker": "SPEAKER_00"},
+ {"start": 5.0, "end": 9.25, "speaker": "SPEAKER_01"},
+ ]
+
+ def test_diarize_turns_from_tracks_rounds_to_milliseconds(self):
+ """Boundary: float noise from the model is rounded away."""
+ tracks = [(Segment(0.03096875, 1.9980000000000002), "_", "SPEAKER_00")]
+ assert diarize.turns_from_tracks(tracks) == [
+ {"start": 0.031, "end": 1.998, "speaker": "SPEAKER_00"}
+ ]
+
+ def test_diarize_turns_from_tracks_drops_empty_segments(self):
+ """Boundary: zero or negative length segments carry no speech."""
+ tracks = [(Segment(2.0, 2.0), "_", "SPEAKER_00"), (Segment(3.0, 2.5), "_", "SPEAKER_00")]
+ assert diarize.turns_from_tracks(tracks) == []
+
+ def test_diarize_turns_from_tracks_empty_input_is_empty_list(self):
+ """Boundary: no tracks."""
+ assert diarize.turns_from_tracks([]) == []
+
+
+class TestParseArgs:
+ def test_diarize_parse_args_speakers_sets_exact_count(self):
+ """Normal: --speakers pins the count."""
+ args = diarize.parse_args(["a.wav", "out.json", "--speakers", "3"])
+ assert (args.audio, args.out, args.speakers) == ("a.wav", "out.json", 3)
+
+ def test_diarize_parse_args_defaults_let_the_model_estimate(self):
+ """Normal: no count given."""
+ args = diarize.parse_args(["a.wav", "out.json"])
+ assert args.speakers is None and args.min_speakers is None and args.max_speakers is None
+
+ @pytest.mark.parametrize("argv", [
+ ["a.wav", "out.json", "--speakers", "0"],
+ ["a.wav", "out.json", "--speakers", "-2"],
+ ["a.wav", "out.json", "--speakers", "three"],
+ ["a.wav", "out.json", "--speakers", "3", "--max-speakers", "5"],
+ ["a.wav", "out.json", "--min-speakers", "4", "--max-speakers", "2"],
+ ["a.wav"],
+ ])
+ def test_diarize_parse_args_rejects_bad_counts(self, argv):
+ """Error: non-positive, non-numeric, contradictory or missing arguments."""
+ with pytest.raises(SystemExit):
+ diarize.parse_args(argv)
+
+
+class TestPipelineKwargs:
+ def test_diarize_pipeline_kwargs_only_passes_what_was_given(self):
+ """Normal: unset options are not forwarded to the model."""
+ args = diarize.parse_args(["a.wav", "o.json", "--min-speakers", "2", "--max-speakers", "4"])
+ assert diarize.pipeline_kwargs(args) == {"min_speakers": 2, "max_speakers": 4}
+ args = diarize.parse_args(["a.wav", "o.json", "--speakers", "3"])
+ assert diarize.pipeline_kwargs(args) == {"num_speakers": 3}
+ assert diarize.pipeline_kwargs(diarize.parse_args(["a.wav", "o.json"])) == {}