Function bodies 405 total
test_download_url_all_models function · rust · L544-L553 (10 LOC)src-tauri/src/services/model_manager.rs
fn test_download_url_all_models() {
let model_names = vec!["tiny", "base", "small", "medium", "large"];
for name in model_names {
let url = get_model_download_url(name).unwrap();
assert!(url.contains("huggingface.co"));
assert!(url.contains("ggerganov/whisper.cpp"));
assert!(url.contains(&format!("ggml-{}.bin", name)));
}
}test_download_url_invalid_model function · rust · L556-L559 (4 LOC)src-tauri/src/services/model_manager.rs
fn test_download_url_invalid_model() {
let url = get_model_download_url("invalid_model");
assert!(url.is_err());
}test_model_file_size_calculation function · rust · L562-L569 (8 LOC)src-tauri/src/services/model_manager.rs
fn test_model_file_size_calculation() {
// Test model size in bytes
assert_eq!(WhisperModel::Tiny.size_bytes(), 74 * 1024 * 1024);
assert_eq!(WhisperModel::Base.size_bytes(), 142 * 1024 * 1024);
assert_eq!(WhisperModel::Small.size_bytes(), 466 * 1024 * 1024);
assert_eq!(WhisperModel::Medium.size_bytes(), 1500 * 1024 * 1024);
assert_eq!(WhisperModel::Large.size_bytes(), 2900 * 1024 * 1024);
}test_model_size_in_mb function · rust · L572-L581 (10 LOC)src-tauri/src/services/model_manager.rs
fn test_model_size_in_mb() {
// Convert to MB for verification
let tiny_mb = WhisperModel::Tiny.size_bytes() as f64 / (1024.0 * 1024.0);
let base_mb = WhisperModel::Base.size_bytes() as f64 / (1024.0 * 1024.0);
let small_mb = WhisperModel::Small.size_bytes() as f64 / (1024.0 * 1024.0);
assert!((tiny_mb - 74.0).abs() < 0.1);
assert!((base_mb - 142.0).abs() < 0.1);
assert!((small_mb - 466.0).abs() < 0.1);
}test_model_display_names function · rust · L584-L590 (7 LOC)src-tauri/src/services/model_manager.rs
fn test_model_display_names() {
assert_eq!(WhisperModel::Tiny.display_name(), "Tiny (74MB)");
assert_eq!(WhisperModel::Base.display_name(), "Base (142MB)");
assert_eq!(WhisperModel::Small.display_name(), "Small (466MB)");
assert_eq!(WhisperModel::Medium.display_name(), "Medium (1.5GB)");
assert_eq!(WhisperModel::Large.display_name(), "Large (2.9GB)");
}test_is_model_downloaded_invalid_name function · rust · L593-L596 (4 LOC)src-tauri/src/services/model_manager.rs
fn test_is_model_downloaded_invalid_name() {
let result = is_model_downloaded("invalid_model");
assert!(result.is_err());
}test_model_from_str_case_insensitive function · rust · L599-L604 (6 LOC)src-tauri/src/services/model_manager.rs
fn test_model_from_str_case_insensitive() {
assert_eq!(WhisperModel::from_str("TINY"), Some(WhisperModel::Tiny));
assert_eq!(WhisperModel::from_str("Tiny"), Some(WhisperModel::Tiny));
assert_eq!(WhisperModel::from_str("tiny"), Some(WhisperModel::Tiny));
assert_eq!(WhisperModel::from_str("SMALL"), Some(WhisperModel::Small));
}Powered by Repobility — scan your code at https://repobility.com
test_model_from_str_invalid function · rust · L607-L610 (4 LOC)src-tauri/src/services/model_manager.rs
fn test_model_from_str_invalid() {
assert_eq!(WhisperModel::from_str("invalid"), None);
assert_eq!(WhisperModel::from_str(""), None);
}test_model_info_serialization function · rust · L613-L644 (32 LOC)src-tauri/src/services/model_manager.rs
fn test_model_info_serialization() {
let info = ModelInfo {
name: "small".to_string(),
display_name: "Small (466MB)".to_string(),
size_bytes: 466 * 1024 * 1024,
is_downloaded: false,
is_active: true,
};
// Test serialization to camelCase
let json = serde_json::to_string_pretty(&info).unwrap();
println!("Serialized JSON: {}", json);
assert!(json.contains(r#""displayName""#));
assert!(json.contains(r#""sizeBytes""#));
assert!(json.contains(r#""isDownloaded""#));
assert!(json.contains(r#""isActive""#));
// Test deserialization from camelCase
let camel_case_json = r#"{
"name": "base",
"displayName": "Base (142MB)",
"sizeBytes": 148897792,
"isDownloaded": true,
"isActive": false
}"#;
let parsed: ModelInfo = serde_json::from_str(camel_case_json).unwrap();
astest_download_stage_serialization function · rust · L647-L662 (16 LOC)src-tauri/src/services/model_manager.rs
fn test_download_stage_serialization() {
let stages = vec![
DownloadStage::Starting,
DownloadStage::Downloading,
DownloadStage::Verifying,
DownloadStage::Complete,
];
for stage in stages {
let json = serde_json::to_string(&stage);
assert!(json.is_ok());
let parsed: Result<DownloadStage, _> = serde_json::from_str(&json.unwrap());
assert!(parsed.is_ok());
}
}test_download_progress_structure function · rust · L665-L690 (26 LOC)src-tauri/src/services/model_manager.rs
fn test_download_progress_structure() {
let progress = ModelDownloadProgress {
model: "small".to_string(),
progress: 50,
stage: DownloadStage::Downloading,
downloaded_bytes: Some(244 * 1024 * 1024),
total_bytes: Some(488 * 1024 * 1024),
};
assert_eq!(progress.model, "small");
assert_eq!(progress.progress, 50);
assert_eq!(progress.downloaded_bytes, Some(244 * 1024 * 1024));
assert_eq!(progress.total_bytes, Some(488 * 1024 * 1024));
// Test without byte counts (for Starting stage)
let start_progress = ModelDownloadProgress {
model: "tiny".to_string(),
progress: 0,
stage: DownloadStage::Starting,
downloaded_bytes: None,
total_bytes: Some(78 * 1024 * 1024),
};
assert_eq!(start_progress.downloaded_bytes, None);
assert_eq!(start_progress.total_bytes, Some(78 * 1024 * 1024));
}test_progress_bounds function · rust · L693-L712 (20 LOC)src-tauri/src/services/model_manager.rs
fn test_progress_bounds() {
// Progress should be 0-100
let progress = ModelDownloadProgress {
model: "test".to_string(),
progress: 0,
stage: DownloadStage::Starting,
downloaded_bytes: None,
total_bytes: None,
};
assert!(progress.progress <= 100);
let progress = ModelDownloadProgress {
model: "test".to_string(),
progress: 100,
stage: DownloadStage::Complete,
downloaded_bytes: Some(1000),
total_bytes: Some(1000),
};
assert!(progress.progress <= 100);
}atomic_write_json function · rust · L38-L68 (31 LOC)src-tauri/src/services/project_io.rs
pub fn atomic_write_json<P: AsRef<Path>>(path: P, data: &Value) -> Result<(), String> {
let path = path.as_ref();
let parent = path
.parent()
.ok_or("File has no parent directory")?;
// Create temp file in same directory (ensures same filesystem for atomic rename)
let temp_path = parent.join(format!("{}.tmp", path.to_string_lossy()));
// Write data to temp file
let mut file = File::create(&temp_path)
.map_err(|e| format!("Failed to create temp file: {}", e))?;
let json_string = serde_json::to_string_pretty(data)
.map_err(|e| format!("Failed to serialize JSON: {}", e))?;
file.write_all(json_string.as_bytes())
.map_err(|e| format!("Failed to write to temp file: {}", e))?;
// Sync to disk (ensure data is physically written to storage)
file.sync_all()
.map_err(|e| format!("Failed to sync temp file: {}", e))?;
// Atomic rename (overwrites destination if exists)
// On Unix: atomic syscall
read_json_file function · rust · L89-L101 (13 LOC)src-tauri/src/services/project_io.rs
pub fn read_json_file<P: AsRef<Path>>(path: P) -> Result<Value, String> {
let path = path.as_ref();
if !path.exists() {
return Err("File does not exist".to_string());
}
let content = fs::read_to_string(path)
.map_err(|e| format!("Failed to read file: {}", e))?;
serde_json::from_str(&content)
.map_err(|e| format!("Failed to parse JSON: {}", e))
}read_json_file_as_string function · rust · L115-L124 (10 LOC)src-tauri/src/services/project_io.rs
pub fn read_json_file_as_string<P: AsRef<Path>>(path: P) -> Result<String, String> {
let path = path.as_ref();
if !path.exists() {
return Err("File does not exist".to_string());
}
fs::read_to_string(path)
.map_err(|e| format!("Failed to read file: {}", e))
}If a scraper extracted this row, it came from Repobility (https://repobility.com)
get_file_extension function · rust · L133-L139 (7 LOC)src-tauri/src/services/project_io.rs
pub fn get_file_extension<P: AsRef<Path>>(path: P) -> String {
path.as_ref()
.extension()
.and_then(|ext| ext.to_str())
.unwrap_or("")
.to_lowercase()
}has_extension function · rust · L149-L151 (3 LOC)src-tauri/src/services/project_io.rs
pub fn has_extension<P: AsRef<Path>>(path: P, extension: &str) -> bool {
get_file_extension(path) == extension.to_lowercase()
}test_atomic_write_creates_valid_file function · rust · L160-L176 (17 LOC)src-tauri/src/services/project_io.rs
fn test_atomic_write_creates_valid_file() {
let temp_file = NamedTempFile::new().unwrap();
let path = temp_file.path();
let data = serde_json::json!({
"format": "1.0",
"meta": { "name": "Test Project" }
});
assert!(atomic_write_json(path, &data).is_ok());
assert!(path.exists());
// Verify content
let read = read_json_file(path).unwrap();
assert_eq!(read["format"], "1.0");
assert_eq!(read["meta"]["name"], "Test Project");
}test_atomic_write_is_atomic function · rust · L179-L192 (14 LOC)src-tauri/src/services/project_io.rs
fn test_atomic_write_is_atomic() {
let temp_file = NamedTempFile::new().unwrap();
let path = temp_file.path();
let data = serde_json::json!({"test": "data"});
atomic_write_json(path, &data).unwrap();
// Verify no temp file left behind
let temp_path = path.with_extension("tmp");
// The temp file should be cleaned up after rename
// Check the path doesn't end with .tmp
assert!(!path.to_string_lossy().ends_with(".tmp"));
}test_atomic_write_overwrites_existing function · rust · L195-L210 (16 LOC)src-tauri/src/services/project_io.rs
fn test_atomic_write_overwrites_existing() {
let temp_file = NamedTempFile::new().unwrap();
let path = temp_file.path();
// Write initial data
let data1 = serde_json::json!({"version": "1"});
atomic_write_json(path, &data1).unwrap();
// Overwrite with new data
let data2 = serde_json::json!({"version": "2"});
atomic_write_json(path, &data2).unwrap();
// Verify only new data exists
let read = read_json_file(path).unwrap();
assert_eq!(read["version"], "2");
}test_read_json_file_not_found function · rust · L213-L217 (5 LOC)src-tauri/src/services/project_io.rs
fn test_read_json_file_not_found() {
let result = read_json_file("/nonexistent/path/file.json");
assert!(result.is_err());
assert!(result.unwrap_err().contains("does not exist"));
}test_read_json_file_invalid_json function · rust · L220-L230 (11 LOC)src-tauri/src/services/project_io.rs
fn test_read_json_file_invalid_json() {
let temp_file = NamedTempFile::new().unwrap();
let path = temp_file.path();
// Write invalid JSON
fs::write(path, b"not valid json").unwrap();
let result = read_json_file(path);
assert!(result.is_err());
assert!(result.unwrap_err().contains("parse JSON"));
}test_get_file_extension function · rust · L233-L238 (6 LOC)src-tauri/src/services/project_io.rs
fn test_get_file_extension() {
assert_eq!(get_file_extension("project.vep"), "vep");
assert_eq!(get_file_extension("video.mp4"), "mp4");
assert_eq!(get_file_extension("no_extension"), "");
assert_eq!(get_file_extension("multiple.dots.json"), "json");
}Generated by Repobility's multi-pass static-analysis pipeline (https://repobility.com)
test_has_extension function · rust · L241-L246 (6 LOC)src-tauri/src/services/project_io.rs
fn test_has_extension() {
assert!(has_extension("project.vep", "vep"));
assert!(has_extension("project.VEP", "vep")); // case insensitive
assert!(!has_extension("project.json", "vep"));
assert!(!has_extension("no_extension", "vep"));
}as_str function · rust · L51-L57 (7 LOC)src-tauri/src/services/segment_analyzer.rs
pub fn as_str(&self) -> &str {
match self {
SegmentType::FillerWord => "filler_word",
SegmentType::Silence => "silence",
SegmentType::Speech => "speech",
}
}default function · rust · L89-L96 (8 LOC)src-tauri/src/services/segment_analyzer.rs
fn default() -> Self {
Self {
min_silence_duration: 0.5,
silence_threshold: 0.02,
min_confidence: 0.5,
segment_padding: 0.05,
}
}generate_segments function · rust · L105-L192 (88 LOC)src-tauri/src/services/segment_analyzer.rs
pub fn generate_segments(
clip_id: &str,
audio_analysis: &AudioAnalysisResult,
filler_detections: &[FillerWordDetection],
config: &SegmentAnalysisConfig,
) -> SegmentAnalysisResult {
let mut segments = Vec::new();
// Add silence segments
for silence in &audio_analysis.silences {
if silence.duration >= config.min_silence_duration
&& silence.confidence >= config.min_confidence
{
segments.push(TimelineSegment {
id: generate_id(),
clip_id: clip_id.to_string(),
start_time: silence.start,
end_time: silence.end,
duration: silence.duration,
segment_type: SegmentType::Silence,
is_active: false, // Silences are inactive by default (will be removed)
confidence: silence.confidence,
manually_edited: false,
content: "silence".to_string(),
});
}
}
merge_overlapping_segments function · rust · L200-L241 (42 LOC)src-tauri/src/services/segment_analyzer.rs
fn merge_overlapping_segments(mut segments: Vec<TimelineSegment>) -> Vec<TimelineSegment> {
if segments.is_empty() {
return segments;
}
// Sort by start time, then by type priority
segments.sort_by(|a, b| {
a.start_time
.partial_cmp(&b.start_time)
.unwrap()
.then_with(|| {
// Filler words have priority over silences
let a_priority = segment_priority(&a.segment_type);
let b_priority = segment_priority(&b.segment_type);
b_priority.cmp(&a_priority)
})
});
let mut merged = Vec::new();
let mut current = segments[0].clone();
for segment in segments.into_iter().skip(1) {
if segment.start_time <= current.end_time + 0.1 {
// Overlapping or adjacent - merge
// Keep the higher priority type
if segment_priority(&segment.segment_type) > segment_priority(¤t.segment_type) {
csegment_priority function · rust · L246-L252 (7 LOC)src-tauri/src/services/segment_analyzer.rs
fn segment_priority(segment_type: &SegmentType) -> i32 {
match segment_type {
SegmentType::FillerWord => 2,
SegmentType::Silence => 1,
SegmentType::Speech => 0,
}
}generate_id function · rust · L257-L264 (8 LOC)src-tauri/src/services/segment_analyzer.rs
fn generate_id() -> String {
let timestamp = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_micros();
format!("segment_{}", timestamp)
}create_speech_segments function · rust · L271-L324 (54 LOC)src-tauri/src/services/segment_analyzer.rs
pub fn create_speech_segments(
segments: &[TimelineSegment],
total_duration: f64,
) -> Vec<TimelineSegment> {
let mut speech_segments = Vec::new();
let mut last_end = 0.0;
// Sort by start time
let mut sorted_segments = segments.to_vec();
sorted_segments.sort_by(|a, b| a.start_time.partial_cmp(&b.start_time).unwrap());
for segment in &sorted_segments {
// Only create speech segment if there's a gap
if segment.start_time > last_end + 0.1 {
let duration = segment.start_time - last_end;
speech_segments.push(TimelineSegment {
id: generate_id(),
clip_id: segment.clip_id.clone(),
start_time: last_end,
end_time: segment.start_time,
duration,
segment_type: SegmentType::Speech,
is_active: true,
confidence: 1.0,
manually_edited: false,
content: "speech".to_string()Repobility analyzer · published findings · https://repobility.com
calculate_edit_stats function · rust · L348-L384 (37 LOC)src-tauri/src/services/segment_analyzer.rs
pub fn calculate_edit_stats(
segments: &[TimelineSegment],
total_duration: f64,
) -> EditStatistics {
let filler_count = segments
.iter()
.filter(|s| matches!(s.segment_type, SegmentType::FillerWord))
.count();
let silence_count = segments
.iter()
.filter(|s| matches!(s.segment_type, SegmentType::Silence))
.count();
let removable_duration: f64 = segments
.iter()
.filter(|s| !s.is_active)
.map(|s| s.duration)
.sum();
let edited_duration = total_duration - removable_duration;
let time_saved = removable_duration;
let removal_percentage = if total_duration > 0.0 {
(removable_duration / total_duration) * 100.0
} else {
0.0
};
EditStatistics {
original_duration: total_duration,
edited_duration,
time_saved,
removal_percentage,
filler_count,
silence_count,
}
}test_segment_merging function · rust · L393-L431 (39 LOC)src-tauri/src/services/segment_analyzer.rs
fn test_segment_merging() {
let segments = vec![
TimelineSegment {
id: "1".into(),
clip_id: "clip1".into(),
start_time: 1.0,
end_time: 2.0,
duration: 1.0,
segment_type: SegmentType::Silence,
is_active: false,
confidence: 0.8,
manually_edited: false,
content: "silence".into(),
},
TimelineSegment {
id: "2".into(),
clip_id: "clip1".into(),
start_time: 1.5,
end_time: 2.5,
duration: 1.0,
segment_type: SegmentType::FillerWord,
is_active: false,
confidence: 0.9,
manually_edited: false,
content: "um".into(),
},
];
let merged = merge_overlapping_segments(segments);
assert_eq!(merged.len(), 1);
test_edit_statistics function · rust · L434-L469 (36 LOC)src-tauri/src/services/segment_analyzer.rs
fn test_edit_statistics() {
let segments = vec![
TimelineSegment {
id: "1".into(),
clip_id: "clip1".into(),
start_time: 0.0,
end_time: 1.0,
duration: 1.0,
segment_type: SegmentType::FillerWord,
is_active: false,
confidence: 0.9,
manually_edited: false,
content: "um".into(),
},
TimelineSegment {
id: "2".into(),
clip_id: "clip1".into(),
start_time: 5.0,
end_time: 6.0,
duration: 1.0,
segment_type: SegmentType::Silence,
is_active: false,
confidence: 0.8,
manually_edited: false,
content: "silence".into(),
},
];
let stats = calculate_edit_stats(&segments, 10.0);
assert_eq!(stats.original_durattest_segment_merging_adjacent function · rust · L472-L507 (36 LOC)src-tauri/src/services/segment_analyzer.rs
fn test_segment_merging_adjacent() {
// Test adjacent segments (within padding threshold)
let segments = vec![
TimelineSegment {
id: "1".into(),
clip_id: "clip1".into(),
start_time: 1.0,
end_time: 2.0,
duration: 1.0,
segment_type: SegmentType::Silence,
is_active: false,
confidence: 0.8,
manually_edited: false,
content: "silence".into(),
},
TimelineSegment {
id: "2".into(),
clip_id: "clip1".into(),
start_time: 2.05, // Within 0.1 threshold
end_time: 3.0,
duration: 0.95,
segment_type: SegmentType::Silence,
is_active: false,
confidence: 0.8,
manually_edited: false,
content: "silence".into(),
},
];
test_segment_merging_non_overlapping function · rust · L510-L543 (34 LOC)src-tauri/src/services/segment_analyzer.rs
fn test_segment_merging_non_overlapping() {
// Test non-overlapping segments
let segments = vec![
TimelineSegment {
id: "1".into(),
clip_id: "clip1".into(),
start_time: 1.0,
end_time: 2.0,
duration: 1.0,
segment_type: SegmentType::Silence,
is_active: false,
confidence: 0.8,
manually_edited: false,
content: "silence".into(),
},
TimelineSegment {
id: "2".into(),
clip_id: "clip1".into(),
start_time: 3.0, // More than 0.1 gap
end_time: 4.0,
duration: 1.0,
segment_type: SegmentType::Silence,
is_active: false,
confidence: 0.8,
manually_edited: false,
content: "silence".into(),
},
];
let mergedtest_segment_merging_nested function · rust · L546-L586 (41 LOC)src-tauri/src/services/segment_analyzer.rs
fn test_segment_merging_nested() {
// Test nested segments (one within another)
let segments = vec![
TimelineSegment {
id: "1".into(),
clip_id: "clip1".into(),
start_time: 1.0,
end_time: 4.0,
duration: 3.0,
segment_type: SegmentType::Silence,
is_active: false,
confidence: 0.8,
manually_edited: false,
content: "silence".into(),
},
TimelineSegment {
id: "2".into(),
clip_id: "clip1".into(),
start_time: 2.0,
end_time: 3.0,
duration: 1.0,
segment_type: SegmentType::FillerWord,
is_active: false,
confidence: 0.9,
manually_edited: false,
content: "um".into(),
},
];
let merged = merge_overlapping_test_segment_merging_empty function · rust · L589-L593 (5 LOC)src-tauri/src/services/segment_analyzer.rs
fn test_segment_merging_empty() {
let segments: Vec<TimelineSegment> = vec![];
let merged = merge_overlapping_segments(segments);
assert_eq!(merged.len(), 0);
}test_segment_merging_single function · rust · L596-L616 (21 LOC)src-tauri/src/services/segment_analyzer.rs
fn test_segment_merging_single() {
let segments = vec![
TimelineSegment {
id: "1".into(),
clip_id: "clip1".into(),
start_time: 1.0,
end_time: 2.0,
duration: 1.0,
segment_type: SegmentType::Silence,
is_active: false,
confidence: 0.8,
manually_edited: false,
content: "silence".into(),
},
];
let merged = merge_overlapping_segments(segments);
assert_eq!(merged.len(), 1);
assert_eq!(merged[0].start_time, 1.0);
assert_eq!(merged[0].end_time, 2.0);
}Powered by Repobility — scan your code at https://repobility.com
test_priority_handling function · rust · L619-L628 (10 LOC)src-tauri/src/services/segment_analyzer.rs
fn test_priority_handling() {
// Test that filler words have higher priority than silences
assert_eq!(segment_priority(&SegmentType::FillerWord), 2);
assert_eq!(segment_priority(&SegmentType::Silence), 1);
assert_eq!(segment_priority(&SegmentType::Speech), 0);
// Filler word > Silence > Speech
assert!(segment_priority(&SegmentType::FillerWord) > segment_priority(&SegmentType::Silence));
assert!(segment_priority(&SegmentType::Silence) > segment_priority(&SegmentType::Speech));
}test_edit_statistics_empty_segments function · rust · L631-L640 (10 LOC)src-tauri/src/services/segment_analyzer.rs
fn test_edit_statistics_empty_segments() {
let segments: Vec<TimelineSegment> = vec![];
let stats = calculate_edit_stats(&segments, 10.0);
assert_eq!(stats.original_duration, 10.0);
assert_eq!(stats.edited_duration, 10.0); // Nothing removed
assert_eq!(stats.time_saved, 0.0);
assert_eq!(stats.filler_count, 0);
assert_eq!(stats.silence_count, 0);
}test_edit_statistics_all_active function · rust · L643-L663 (21 LOC)src-tauri/src/services/segment_analyzer.rs
fn test_edit_statistics_all_active() {
let segments = vec![
TimelineSegment {
id: "1".into(),
clip_id: "clip1".into(),
start_time: 0.0,
end_time: 1.0,
duration: 1.0,
segment_type: SegmentType::Speech,
is_active: true, // Active, won't be removed
confidence: 0.9,
manually_edited: false,
content: "speech".into(),
},
];
let stats = calculate_edit_stats(&segments, 10.0);
assert_eq!(stats.time_saved, 0.0); // No inactive segments
assert_eq!(stats.removal_percentage, 0.0);
}test_edit_statistics_mixed_active_states function · rust · L666-L701 (36 LOC)src-tauri/src/services/segment_analyzer.rs
fn test_edit_statistics_mixed_active_states() {
let segments = vec![
TimelineSegment {
id: "1".into(),
clip_id: "clip1".into(),
start_time: 0.0,
end_time: 1.0,
duration: 1.0,
segment_type: SegmentType::FillerWord,
is_active: false, // Will be removed
confidence: 0.9,
manually_edited: false,
content: "um".into(),
},
TimelineSegment {
id: "2".into(),
clip_id: "clip1".into(),
start_time: 2.0,
end_time: 3.0,
duration: 1.0,
segment_type: SegmentType::FillerWord,
is_active: true, // Won't be removed (user kept it)
confidence: 0.9,
manually_edited: true,
content: "um".into(),
},
];
let stats = calculatest_removal_percentage_calculation function · rust · L704-L724 (21 LOC)src-tauri/src/services/segment_analyzer.rs
fn test_removal_percentage_calculation() {
let segments = vec![
TimelineSegment {
id: "1".into(),
clip_id: "clip1".into(),
start_time: 0.0,
end_time: 5.0,
duration: 5.0,
segment_type: SegmentType::Silence,
is_active: false,
confidence: 0.8,
manually_edited: false,
content: "silence".into(),
},
];
let stats = calculate_edit_stats(&segments, 10.0);
// 5 seconds removed out of 10 = 50%
assert_eq!(stats.removal_percentage, 50.0);
}test_removal_percentage_zero_duration function · rust · L727-L733 (7 LOC)src-tauri/src/services/segment_analyzer.rs
fn test_removal_percentage_zero_duration() {
let segments: Vec<TimelineSegment> = vec![];
let stats = calculate_edit_stats(&segments, 0.0);
// Should handle zero duration gracefully
assert_eq!(stats.removal_percentage, 0.0);
}test_create_speech_segments function · rust · L736-L760 (25 LOC)src-tauri/src/services/segment_analyzer.rs
fn test_create_speech_segments() {
let segments = vec![
TimelineSegment {
id: "1".into(),
clip_id: "clip1".into(),
start_time: 2.0,
end_time: 3.0,
duration: 1.0,
segment_type: SegmentType::FillerWord,
is_active: false,
confidence: 0.9,
manually_edited: false,
content: "um".into(),
},
];
let speech_segments = create_speech_segments(&segments, 5.0);
// Should create speech segments before and after the filler
assert_eq!(speech_segments.len(), 2);
assert_eq!(speech_segments[0].start_time, 0.0);
assert_eq!(speech_segments[0].end_time, 2.0);
assert_eq!(speech_segments[1].start_time, 3.0);
assert_eq!(speech_segments[1].end_time, 5.0);
}test_create_speech_segments_no_gaps function · rust · L763-L783 (21 LOC)src-tauri/src/services/segment_analyzer.rs
fn test_create_speech_segments_no_gaps() {
let segments = vec![
TimelineSegment {
id: "1".into(),
clip_id: "clip1".into(),
start_time: 0.0,
end_time: 5.0,
duration: 5.0,
segment_type: SegmentType::FillerWord,
is_active: false,
confidence: 0.9,
manually_edited: false,
content: "um".into(),
},
];
let speech_segments = create_speech_segments(&segments, 5.0);
// No gaps, so no speech segments
assert_eq!(speech_segments.len(), 0);
}If a scraper extracted this row, it came from Repobility (https://repobility.com)
test_segment_type_as_str function · rust · L786-L790 (5 LOC)src-tauri/src/services/segment_analyzer.rs
fn test_segment_type_as_str() {
assert_eq!(SegmentType::FillerWord.as_str(), "filler_word");
assert_eq!(SegmentType::Silence.as_str(), "silence");
assert_eq!(SegmentType::Speech.as_str(), "speech");
}test_config_default_values function · rust · L793-L799 (7 LOC)src-tauri/src/services/segment_analyzer.rs
fn test_config_default_values() {
let config = SegmentAnalysisConfig::default();
assert_eq!(config.min_silence_duration, 0.5);
assert_eq!(config.silence_threshold, 0.02);
assert_eq!(config.min_confidence, 0.5);
assert_eq!(config.segment_padding, 0.05);
}default function · rust · L30-L34 (5 LOC)src-tauri/src/services/settings.rs
fn default() -> Self {
Self {
theme: ThemeMode::Dark,
}
}