from __future__ import annotations import importlib.util import json import tempfile import unittest from pathlib import Path from turn_detection.runtime.features import FrontendConfig from turn_detection.runtime.predictor import ModelMetadata class FrontendConfigTest(unittest.TestCase): def test_frame_contract(self) -> None: config = FrontendConfig() self.assertEqual(config.max_samples, 128_000) self.assertEqual(config.target_frames, 800) def test_invalid_bounds_are_rejected(self) -> None: with self.assertRaises(ValueError): FrontendConfig(f_max=20_000) def test_metadata_round_trip(self) -> None: metadata = ModelMetadata(model_name="smoke", architecture="tinytcn") with tempfile.TemporaryDirectory() as directory: path = Path(directory) / "model_metadata.json" path.write_text(json.dumps(metadata.to_dict()), encoding="utf-8") loaded = ModelMetadata.from_path(path) self.assertEqual(loaded, metadata) @unittest.skipUnless( importlib.util.find_spec("numpy"), "numpy is optional in this test environment" ) def test_features_have_expected_shape_and_finite_values(self) -> None: import numpy as np from turn_detection.runtime.features import log_mel_spectrogram audio = np.zeros(16_000, dtype=np.float32) features, mask = log_mel_spectrogram(audio, 16_000) self.assertEqual(features.shape, (80, 800)) self.assertEqual(mask.shape, (800,)) self.assertTrue(np.isfinite(features).all()) self.assertEqual(int(mask.sum()), 100) if __name__ == "__main__": unittest.main()