Coverage for tests/test_tts_utils.py: 99%
79 statements
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-09 04:47 +0000
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-09 04:47 +0000
1"""
2Unit tests for tts_utils.py
3"""
4import os
5import pytest
7from media_utils import empty_audio_file
8from file_utils import read_file_base64
9from media_utils import get_audio_duration
11from tts_utils import get_audio_chunks_by_silences
12from tts_utils import split_into_sentences_max_duration
13from tts_utils import strip_audio_file_silence
14from tts_utils import generate_waveform_plt
15from tts_utils import merge_chunks
18def test_empy_audio_chunk() -> None:
19 audio_path = empty_audio_file(duration_seconds=7.3)
20 chunks = get_audio_chunks_by_silences(audio_path)
21 assert len(chunks) == 2
23 chunk0 = chunks[0]
24 assert chunk0[0] == 0.0
25 assert chunk0[1] == 3.65
27 chunk1 = chunks[1]
28 assert chunk1[0] == 3.65
29 assert chunk1[1] == 7.3
32def test_audio_sample_chunk() -> None:
33 audio_path = "tests/data/audio_24secs.wav"
34 if not os.path.exists(audio_path):
35 return
37 chunks = get_audio_chunks_by_silences(audio_path)
38 assert len(chunks) == 5
39 assert chunks[0][0] == 0.0
40 for chunk_start, chunk_end in chunks:
41 assert chunk_start < chunk_end
44def test_split_sentences() -> None:
45 text = ("This is a test. " * 20) + ("This sentence is way too long " * 50) + ("Short one. " * 10)
46 chunks = split_into_sentences_max_duration(text, max_duration=3.0)
47 assert len(chunks) > 1
48 for chunk in chunks:
49 assert 0 < len(chunk) < 5000 # Arbitrary limit to avoid extremely long chunks
51 assert split_into_sentences_max_duration(None, max_duration=3.0) == [] # type: ignore[arg-type]
52 assert split_into_sentences_max_duration("", max_duration=3.0) == []
53 assert split_into_sentences_max_duration(" ", max_duration=3.0) == [" "]
54 assert split_into_sentences_max_duration(" Test ", max_duration=3.0) == [" Test "]
55 assert split_into_sentences_max_duration(" Test1. Test2. ", max_duration=3.0) == [" Test1. Test2. "]
58@pytest.mark.asyncio
59async def test_fit_audio_to_duration() -> None:
60 audio_path = "tests/data/audio_24secs.wav"
61 audio_base64 = await read_file_base64(audio_path)
62 duration_secs = get_audio_duration(audio_base64)
63 assert duration_secs == 24.025
65 stripped_end_audio_path = strip_audio_file_silence(audio_path, strip_start=False, strip_end=True)
66 stripped_end_audio_base64 = await read_file_base64(stripped_end_audio_path)
67 assert stripped_end_audio_base64.startswith("UklGR")
68 stripped_end_duration_secs = get_audio_duration(stripped_end_audio_base64)
69 assert stripped_end_duration_secs < duration_secs
70 os.unlink(stripped_end_audio_path)
72 stripped_audio_path = strip_audio_file_silence(audio_path, strip_start=True, strip_end=True)
73 stripped_audio_base64 = await read_file_base64(stripped_audio_path)
74 assert stripped_audio_base64.startswith("UklGR")
75 stripped_duration_secs = get_audio_duration(stripped_audio_base64)
76 assert stripped_duration_secs < stripped_end_duration_secs
77 os.unlink(stripped_audio_path)
80def test_generate_waveform_plt() -> None:
81 audio_path = "tests/data/sample.wav"
82 waveform_path = generate_waveform_plt(audio_path)
83 assert waveform_path.endswith(".png")
84 assert os.path.exists(waveform_path)
85 assert os.path.getsize(waveform_path) > 0
86 with open(waveform_path, "rb") as file:
87 png_bytes = file.read()
88 assert png_bytes.startswith(b"\x89PNG\r\n\x1a\n")
89 os.unlink(waveform_path)
92def test_merge_chunks() -> None:
93 chunks = [(0.0, 1.5), (1.5, 2.0), (2.0, 3.0), (3.0, 5.0)]
94 assert merge_chunks(chunks, max_duration_seconds=10.0) == [(0.0, 5.0)]
95 assert merge_chunks(chunks, max_duration_seconds=5.0) == [(0.0, 5.0)]
96 assert merge_chunks(chunks, max_duration_seconds=2.0) == [(0.0, 2.0), (2.0, 3.0), (3.0, 5.0)]
97 assert merge_chunks(chunks, max_duration_seconds=1.0) == [(0.0, 1.5), (1.5, 2.0), (2.0, 3.0), (3.0, 5.0)]
98 assert merge_chunks(chunks, max_duration_seconds=0.0) == [(0.0, 1.5), (1.5, 2.0), (2.0, 3.0), (3.0, 5.0)]
99 assert merge_chunks(chunks, max_duration_seconds=-1.0) == [(0.0, 1.5), (1.5, 2.0), (2.0, 3.0), (3.0, 5.0)]
101 assert merge_chunks(None) is None # type: ignore[arg-type]
102 assert merge_chunks([]) == []
103 assert merge_chunks([(0.0, 1.5)]) == [(0.0, 1.5)]