|
|
|
|
|
import os |
|
import glob |
|
import time |
|
import unittest |
|
import subprocess |
|
|
|
from services.tts_service import generate_audio |
|
from services.manim_service import create_manim_video |
|
|
|
|
|
from pydub import AudioSegment |
|
|
|
|
|
class TestTTSService(unittest.TestCase): |
|
def setUp(self): |
|
|
|
self.audio_file = "output.wav" |
|
if os.path.exists(self.audio_file): |
|
os.remove(self.audio_file) |
|
|
|
def test_generate_audio(self): |
|
sample_text = "This is a test narration for the TTS service." |
|
output_file = generate_audio(sample_text) |
|
|
|
self.assertTrue(os.path.exists(output_file), "TTS output file was not created.") |
|
self.assertGreater(os.path.getsize(output_file), 0, "TTS output file is empty.") |
|
|
|
|
|
audio = AudioSegment.from_wav(output_file) |
|
self.assertGreater(audio.duration_seconds, 0, "TTS audio file has zero duration.") |
|
self.assertNotEqual(audio.dBFS, float("-inf"), "Generated audio is completely silent.") |
|
self.assertGreater(audio.dBFS, -35, "Audio seems too quiet; it may be silent.") |
|
|
|
|
|
print(f"Test audio file saved at: {os.path.abspath(output_file)}") |
|
|
|
|
|
|
|
class TestManimService(unittest.TestCase): |
|
def setUp(self): |
|
|
|
self.manim_py = "generated_video.py" |
|
if os.path.exists(self.manim_py): |
|
os.remove(self.manim_py) |
|
|
|
self.video_files = glob.glob("media/videos/generated_video/**/*.mp4", recursive=True) |
|
for f in self.video_files: |
|
os.remove(f) |
|
|
|
def test_create_manim_video_with_audio(self): |
|
|
|
dummy_code = """ |
|
from manim import * |
|
|
|
class TestScene(Scene): |
|
def construct(self): |
|
self.wait(5) |
|
""" |
|
video_data = {"output_file": "output.mp4", "manim_code": dummy_code} |
|
|
|
|
|
audio_file = generate_audio("Test narration for merging with the Manim video.") |
|
self.assertTrue(os.path.exists(audio_file), "TTS audio file for merging was not created.") |
|
|
|
|
|
create_manim_video(video_data, dummy_code, audio_file=audio_file) |
|
|
|
|
|
time.sleep(10) |
|
|
|
|
|
video_paths = glob.glob("media/videos/generated_video/**/*.mp4", recursive=True) |
|
if not video_paths: |
|
|
|
self.assertTrue(os.path.exists("output.mp4"), "No video file was produced by Manim.") |
|
|
|
|
|
def test_generate_audio_empty_text(self): |
|
"""Test TTS service with empty text input""" |
|
with self.assertRaises(ValueError): |
|
generate_audio("") |
|
|
|
def test_generate_audio_long_text(self): |
|
"""Test TTS with longer text input""" |
|
long_text = "This is a longer test narrative. " * 10 |
|
output_file = generate_audio(long_text) |
|
self.assertTrue(os.path.exists(output_file)) |
|
audio = AudioSegment.from_mp3(output_file) |
|
self.assertGreater(audio.duration_seconds, 5) |
|
os.remove(output_file) |
|
|
|
def test_create_manim_video_without_audio(self): |
|
"""Test video creation without audio""" |
|
dummy_code = """ |
|
class TestScene(Scene): |
|
def construct(self): |
|
circle = Circle() |
|
self.play(Create(circle)) |
|
self.wait(2) |
|
""" |
|
video_data = {"output_file": "output.mp4", "manim_code": dummy_code} |
|
create_manim_video(video_data, dummy_code) |
|
|
|
time.sleep(5) |
|
video_paths = glob.glob("media/videos/generated_video/**/*.mp4", recursive=True) |
|
self.assertTrue(video_paths, "No video file was produced") |
|
|
|
for f in video_paths: |
|
self.assertGreater(os.path.getsize(f), 0) |
|
os.remove(f) |
|
|
|
def test_create_manim_video_invalid_code(self): |
|
"""Test handling of invalid Manim code""" |
|
invalid_code = "This is not valid Python code" |
|
video_data = {"output_file": "output.mp4", "manim_code": invalid_code} |
|
with self.assertRaises(subprocess.CalledProcessError): |
|
create_manim_video(video_data, invalid_code) |
|
|
|
def test_create_manim_video_with_text(self): |
|
"""Test video creation with text elements""" |
|
code_with_text = """ |
|
class TextScene(Scene): |
|
def construct(self): |
|
text = Text("Hello World") |
|
self.play(Write(text)) |
|
self.wait(2) |
|
""" |
|
video_data = {"output_file": "output.mp4", "manim_code": code_with_text} |
|
create_manim_video(video_data, code_with_text) |
|
|
|
time.sleep(5) |
|
video_paths = glob.glob("media/videos/generated_video/**/*.mp4", recursive=True) |
|
self.assertTrue(video_paths) |
|
|
|
for f in video_paths: |
|
self.assertGreater(os.path.getsize(f), 0) |
|
os.remove(f) |
|
|
|
def test_audio_video_sync(self): |
|
"""Test audio-video synchronization""" |
|
dummy_code = """ |
|
class SyncScene(Scene): |
|
def construct(self): |
|
circle = Circle() |
|
self.play(Create(circle), run_time=3) |
|
self.wait(2) |
|
""" |
|
video_data = {"output_file": "output.mp4", "manim_code": dummy_code} |
|
audio_text = "This circle appears over three seconds and then waits for two more seconds." |
|
audio_file = generate_audio(audio_text) |
|
|
|
create_manim_video(video_data, dummy_code, audio_file=audio_file) |
|
|
|
time.sleep(10) |
|
video_paths = glob.glob("media/videos/generated_video/**/*.mp4", recursive=True) |
|
self.assertTrue(video_paths) |
|
|
|
|
|
for f in video_paths: |
|
os.remove(f) |
|
os.remove(audio_file) |