Skip to main content

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