Files
meeting-lab/tests/test_convert_whispercpp_json.py
T
2026-08-04 16:57:28 +02:00

146 lines
5.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import json
import tempfile
import unittest
from pathlib import Path
from scripts.convert_whispercpp_json import (
WhisperCppConversionError,
convert_entries,
convert_whispercpp_json,
format_timestamp,
)
def whispercpp_entry(
text: str,
offset_from: int,
offset_to: int,
timestamp_from: str = "00:00:00,000",
timestamp_to: str = "00:00:01,000",
) -> dict:
return {
"timestamps": {"from": timestamp_from, "to": timestamp_to},
"offsets": {"from": offset_from, "to": offset_to},
"text": text,
}
class ConvertWhisperCppJsonTests(unittest.TestCase):
def test_valid_whispercpp_json_writes_compact_json_and_text(self) -> None:
with tempfile.TemporaryDirectory() as directory:
root = Path(directory)
input_path = root / "whispercpp.json"
json_output = root / "converted.json"
text_output = root / "converted.txt"
input_path.write_text(
json.dumps(
{
"transcription": [
whispercpp_entry(" Hello ", 0, 12340),
whispercpp_entry("world", 12340, 13000),
]
},
ensure_ascii=False,
),
encoding="utf-8",
)
summary = convert_whispercpp_json(input_path, json_output, text_output)
converted = json.loads(json_output.read_text(encoding="utf-8"))
self.assertEqual(converted["text"], "Hello world")
self.assertEqual(
converted["segments"],
[
{"id": 0, "start": 0.0, "end": 12.34, "text": "Hello"},
{"id": 1, "start": 12.34, "end": 13.0, "text": "world"},
],
)
self.assertEqual(
text_output.read_text(encoding="utf-8"),
"[00:00:00.000 - 00:00:12.340] Hello\n"
"[00:00:12.340 - 00:00:13.000] world\n",
)
self.assertEqual(summary["original_entry_count"], 2)
self.assertEqual(summary["retained_segment_count"], 2)
self.assertEqual(summary["total_character_count"], len("Hello world"))
self.assertEqual(summary["detected_total_duration"], 13.0)
def test_empty_segments_are_skipped_and_ids_are_renumbered(self) -> None:
converted = convert_entries(
[
whispercpp_entry("first", 0, 1000),
whispercpp_entry(" ", 1000, 2000),
whispercpp_entry("", 2000, 3000),
whispercpp_entry("second", 3000, 4000),
]
)
self.assertEqual(converted["text"], "first second")
self.assertEqual(
converted["segments"],
[
{"id": 0, "start": 0.0, "end": 1.0, "text": "first"},
{"id": 1, "start": 3.0, "end": 4.0, "text": "second"},
],
)
def test_missing_transcription_list_is_rejected(self) -> None:
with tempfile.TemporaryDirectory() as directory:
input_path = Path(directory) / "missing.json"
input_path.write_text(json.dumps({"segments": []}), encoding="utf-8")
with self.assertRaisesRegex(
WhisperCppConversionError,
"Input JSON must contain a 'transcription' list.",
):
convert_whispercpp_json(input_path)
def test_malformed_offsets_are_rejected(self) -> None:
with self.assertRaisesRegex(
WhisperCppConversionError,
r"transcription\[0\]\.offsets\.from must be a number.",
):
convert_entries([whispercpp_entry("bad", "0", 1000)])
with self.assertRaisesRegex(
WhisperCppConversionError,
r"offsets\.to must be greater than or equal to offsets\.from",
):
convert_entries([whispercpp_entry("bad", 2000, 1000)])
def test_utf8_text_is_preserved(self) -> None:
converted = convert_entries(
[
whispercpp_entry(" Grüße für Marleen – HÜSKER ", 0, 1000),
]
)
self.assertEqual(converted["text"], "Grüße für Marleen – HÜSKER")
self.assertEqual(
converted["segments"][0]["text"],
"Grüße für Marleen – HÜSKER",
)
def test_ordering_is_preserved(self) -> None:
converted = convert_entries(
[
whispercpp_entry("third spoken first", 3000, 4000),
whispercpp_entry("first spoken second", 0, 1000),
whispercpp_entry("second spoken third", 1000, 2000),
]
)
self.assertEqual(
[segment["text"] for segment in converted["segments"]],
["third spoken first", "first spoken second", "second spoken third"],
)
def test_format_timestamp_uses_hours_minutes_seconds_milliseconds(self) -> None:
self.assertEqual(format_timestamp(123.45), "00:02:03.450")
self.assertEqual(format_timestamp(3723.004), "01:02:03.004")
if __name__ == "__main__":
unittest.main()