lc/
test_utils.rs

1//! Test utilities for managing test providers and cleanup
2//! 
3//! This module provides utilities to ensure test providers use the "test-" prefix
4//! and are automatically cleaned up after tests complete.
5
6use std::fs;
7use std::sync::Once;
8
9/// Prefix for test providers to avoid conflicts with real configurations
10pub const TEST_PROVIDER_PREFIX: &str = "test-";
11
12static INIT: Once = Once::new();
13
14/// Initialize test environment - call this once at the start of test runs
15pub fn init_test_env() {
16    INIT.call_once(|| {
17        cleanup_test_providers().unwrap_or_else(|e| {
18            eprintln!("Warning: Failed to clean up test providers during init: {}", e);
19        });
20    });
21}
22
23/// Clean up test providers from the configuration directory
24pub fn cleanup_test_providers() -> Result<(), Box<dyn std::error::Error>> {
25    let home_dir = dirs::home_dir().ok_or("Could not find home directory")?;
26    let config_dir = home_dir.join("Library/Application Support/lc/providers");
27    
28    if !config_dir.exists() {
29        return Ok(());
30    }
31    
32    let mut cleaned_count = 0;
33    
34    // Read directory and remove any files that start with test- prefix
35    for entry in fs::read_dir(&config_dir)? {
36        let entry = entry?;
37        let file_name = entry.file_name();
38        let file_name_str = file_name.to_string_lossy();
39        
40        if file_name_str.starts_with(TEST_PROVIDER_PREFIX) {
41            let file_path = entry.path();
42            if file_path.is_file() {
43                fs::remove_file(&file_path)?;
44                cleaned_count += 1;
45            }
46        }
47    }
48    
49    if cleaned_count > 0 {
50        println!("Cleaned up {} test provider files", cleaned_count);
51    }
52    
53    Ok(())
54}
55
56/// Get test provider name with prefix
57pub fn get_test_provider_name(base_name: &str) -> String {
58    format!("{}{}", TEST_PROVIDER_PREFIX, base_name)
59}
60
61/// RAII guard for test cleanup
62pub struct TestGuard;
63
64impl TestGuard {
65    pub fn new() -> Self {
66        init_test_env();
67        TestGuard
68    }
69}
70
71impl Drop for TestGuard {
72    fn drop(&mut self) {
73        if let Err(e) = cleanup_test_providers() {
74            eprintln!("Warning: Failed to clean up test providers: {}", e);
75        }
76    }
77}
78
79/// Macro to wrap test functions with automatic setup and cleanup
80#[macro_export]
81macro_rules! test_with_cleanup {
82    ($test_body:block) => {{
83        let _guard = $crate::test_utils::TestGuard::new();
84        $test_body
85    }};
86}
87
88#[cfg(test)]
89mod tests {
90    use super::*;
91
92    #[test]
93    fn test_provider_name_generation() {
94        assert_eq!(get_test_provider_name("openai"), "test-openai");
95        assert_eq!(get_test_provider_name("anthropic"), "test-anthropic");
96        assert_eq!(get_test_provider_name("custom-provider"), "test-custom-provider");
97    }
98
99    #[test]
100    fn test_cleanup_function() {
101        // Test that cleanup function can be called without errors
102        let result = cleanup_test_providers();
103        assert!(result.is_ok());
104    }
105
106    #[test]
107    fn test_guard_creation() {
108        let _guard = TestGuard::new();
109        // If we get here, the guard was created successfully
110    }
111}