#![allow(clippy::expect_used)]
use super::*;
#[test]
fn test_embedding_config_default() {
let config = EmbeddingConfig::default();
assert_eq!(config.embedding_dim, 256);
assert!(config.normalize);
assert!(config.use_mean_pooling);
}
#[test]
fn test_embedding_config_for_realtime() {
let config = EmbeddingConfig::for_realtime();
assert!((config.window_size - 1.0).abs() < f32::EPSILON);
assert!((config.hop_size - 0.5).abs() < f32::EPSILON);
}
#[test]
fn test_embedding_config_for_accuracy() {
let config = EmbeddingConfig::for_accuracy();
assert!((config.window_size - 2.0).abs() < f32::EPSILON);
}
#[test]
fn test_embedding_config_with_window_size() {
let config = EmbeddingConfig::default().with_window_size(3.0);
assert!((config.window_size - 3.0).abs() < f32::EPSILON);
}
#[test]
fn test_speaker_embedding_new() {
let vec = vec![0.1; 256];
let emb = SpeakerEmbedding::new(vec.clone(), 0);
assert_eq!(emb.speaker_id(), 0);
assert_eq!(emb.dim(), 256);
assert!((emb.confidence() - 1.0).abs() < f32::EPSILON);
}
#[test]
fn test_speaker_embedding_with_confidence() {
let emb = SpeakerEmbedding::new(vec![0.1; 256], 0).with_confidence(0.8);
assert!((emb.confidence() - 0.8).abs() < f32::EPSILON);
}
#[test]
fn test_speaker_embedding_cosine_similarity_identical() {
let emb1 = SpeakerEmbedding::new(vec![1.0, 0.0, 0.0], 0);
let emb2 = SpeakerEmbedding::new(vec![1.0, 0.0, 0.0], 0);
let sim = emb1.cosine_similarity(&emb2);
assert!((sim - 1.0).abs() < 0.001);
}
#[test]
fn test_speaker_embedding_cosine_similarity_orthogonal() {
let emb1 = SpeakerEmbedding::new(vec![1.0, 0.0, 0.0], 0);
let emb2 = SpeakerEmbedding::new(vec![0.0, 1.0, 0.0], 0);
let sim = emb1.cosine_similarity(&emb2);
assert!(sim.abs() < 0.001);
}
#[test]
fn test_speaker_embedding_cosine_similarity_opposite() {
let emb1 = SpeakerEmbedding::new(vec![1.0, 0.0, 0.0], 0);
let emb2 = SpeakerEmbedding::new(vec![-1.0, 0.0, 0.0], 0);
let sim = emb1.cosine_similarity(&emb2);
assert!((sim + 1.0).abs() < 0.001);
}
#[test]
fn test_speaker_embedding_euclidean_distance() {
let emb1 = SpeakerEmbedding::new(vec![0.0, 0.0, 0.0], 0);
let emb2 = SpeakerEmbedding::new(vec![3.0, 4.0, 0.0], 0);
let dist = emb1.euclidean_distance(&emb2);
assert!((dist - 5.0).abs() < 0.001);
}
#[test]
fn test_speaker_embedding_normalized() {
let emb = SpeakerEmbedding::new(vec![3.0, 4.0], 0);
let normalized = emb.normalized();
let norm: f32 = normalized
.vector()
.iter()
.map(|x| x * x)
.sum::<f32>()
.sqrt();
assert!((norm - 1.0).abs() < 0.001);
}
#[test]
fn test_speaker_embedding_mean() {
let embeddings = vec![
SpeakerEmbedding::new(vec![1.0, 2.0, 3.0], 0),
SpeakerEmbedding::new(vec![3.0, 4.0, 5.0], 0),
];
let mean = SpeakerEmbedding::mean(&embeddings).expect("should compute mean");
assert!((mean.vector()[0] - 2.0).abs() < 0.001);
assert!((mean.vector()[1] - 3.0).abs() < 0.001);
assert!((mean.vector()[2] - 4.0).abs() < 0.001);
}
#[test]
fn test_speaker_embedding_mean_empty() {
let embeddings: Vec<SpeakerEmbedding> = vec![];
let mean = SpeakerEmbedding::mean(&embeddings);
assert!(mean.is_none());
}
#[test]
fn test_speaker_embedding_model_default() {
let model = SpeakerEmbeddingModel::default();
assert_eq!(model, SpeakerEmbeddingModel::MfccSimple);
}
#[test]
fn test_embedding_extractor_new() {
let config = EmbeddingConfig::default();
let extractor = EmbeddingExtractor::new(config);
assert_eq!(extractor.config().embedding_dim, 256);
}
#[test]
fn test_embedding_extractor_with_model() {
let extractor = EmbeddingExtractor::new(EmbeddingConfig::default())
.with_model(SpeakerEmbeddingModel::XVector);
assert!(extractor.config().normalize);
}
#[test]
fn test_embedding_extractor_extract_empty() {
let extractor = EmbeddingExtractor::new(EmbeddingConfig::default());
let result = extractor.extract(&[], 16000);
assert!(result.is_err());
}
#[test]
fn test_embedding_extractor_extract_short_audio() {
let extractor = EmbeddingExtractor::new(EmbeddingConfig::default());
let audio = vec![0.1; 100]; let result = extractor.extract(&audio, 16000);
assert!(result.is_err());
}
#[test]
fn test_embedding_extractor_extract_valid_audio() {
let extractor = EmbeddingExtractor::new(EmbeddingConfig::default());
let audio: Vec<f32> = (0..16000).map(|i| (i as f32 * 0.01).sin() * 0.5).collect();
let result = extractor.extract(&audio, 16000);
assert!(result.is_ok());
let embedding = result.expect("should succeed");
assert_eq!(embedding.dim(), 256);
}
#[test]
fn test_embedding_extractor_extract_normalized() {
let config = EmbeddingConfig::default();
let extractor = EmbeddingExtractor::new(config);
let audio: Vec<f32> = (0..16000).map(|i| (i as f32 * 0.01).sin() * 0.5).collect();
let embedding = extractor.extract(&audio, 16000).expect("should succeed");
let norm: f32 = embedding.vector().iter().map(|x| x * x).sum::<f32>().sqrt();
assert!((norm - 1.0).abs() < 0.1 || norm < f32::EPSILON);
}
#[test]
fn test_embedding_extractor_resample() {
let extractor = EmbeddingExtractor::new(EmbeddingConfig::default());
let audio: Vec<f32> = vec![0.0, 1.0, 0.0, -1.0];
let resampled = extractor.resample(&audio, 8000, 16000);
assert!(resampled.len() > audio.len());
}
#[test]
fn test_hz_to_mel_to_hz() {
let hz: f32 = 1000.0;
let mel = EmbeddingExtractor::hz_to_mel(hz);
let hz_back = EmbeddingExtractor::mel_to_hz(mel);
assert!((hz - hz_back).abs() < 0.1);
}
#[test]
fn test_dct_matrix_dimensions() {
let matrix = EmbeddingExtractor::compute_dct_matrix(40, 80);
assert_eq!(matrix.len(), 40);
assert_eq!(matrix[0].len(), 80);
}
#[test]
fn test_mel_filterbank_dimensions() {
let filterbank = EmbeddingExtractor::compute_mel_filterbank(80, 512, 16000);
assert_eq!(filterbank.len(), 80);
assert_eq!(filterbank[0].len(), 257); }
#[test]
fn test_embedding_config_with_hop_size() {
let config = EmbeddingConfig::default().with_hop_size(0.25);
assert!((config.hop_size - 0.25).abs() < f32::EPSILON);
}
#[test]
fn test_embedding_config_with_hop_size_small() {
let config = EmbeddingConfig::default().with_hop_size(0.1);
assert!((config.hop_size - 0.1).abs() < f32::EPSILON);
}
#[test]
fn test_embedding_config_with_hop_and_window() {
let config = EmbeddingConfig::default()
.with_window_size(3.0)
.with_hop_size(1.5);
assert!((config.window_size - 3.0).abs() < f32::EPSILON);
assert!((config.hop_size - 1.5).abs() < f32::EPSILON);
}
#[test]
fn test_embedding_config_with_hop_size_large() {
let config = EmbeddingConfig::default().with_hop_size(2.0);
assert!((config.hop_size - 2.0).abs() < f32::EPSILON);
assert_eq!(config.embedding_dim, EMBEDDING_DIM);
assert!(config.normalize);
}
#[test]
fn test_embedding_config_with_hop_size_preserves_other_fields() {
let config = EmbeddingConfig::for_accuracy().with_hop_size(0.3);
assert!((config.hop_size - 0.3).abs() < f32::EPSILON);
assert!((config.window_size - 2.0).abs() < f32::EPSILON);
assert!(config.use_mean_pooling);
}