use help_probe::cache::{CacheConfig, generate_cache_key, read_cache, write_cache};
use help_probe::model::ProbeResult;
use tempfile::TempDir;
#[test]
fn test_generate_cache_key() {
let key1 = generate_cache_key("ls", &["--help".to_string()]);
let key2 = generate_cache_key("ls", &["--help".to_string()]);
let key3 = generate_cache_key("ls", &["-h".to_string()]);
assert_eq!(key1, key2); assert_ne!(key1, key3); }
#[test]
fn test_cache_read_write() {
let temp_dir = TempDir::new().unwrap();
let config = CacheConfig {
cache_dir: temp_dir.path().to_path_buf(),
enabled: true,
max_age_secs: None,
};
let result = ProbeResult {
command: "test-cmd".to_string(),
args: vec!["--help".to_string()],
exit_code: Some(0),
timed_out: false,
help_flag_detected: true,
usage_blocks: vec![],
options: vec![],
subcommands: vec![],
arguments: vec![],
examples: vec![],
environment_variables: vec![],
validation_rules: vec![],
raw_stdout: "test output".to_string(),
raw_stderr: String::new(),
};
write_cache("test-cmd", &["--help".to_string()], &result, &config).unwrap();
let cached = read_cache("test-cmd", &["--help".to_string()], &config).unwrap();
assert!(cached.is_some());
let cached_result = cached.unwrap();
assert_eq!(cached_result.command, "test-cmd");
assert_eq!(cached_result.raw_stdout, "test output");
}
#[test]
fn test_cache_miss() {
let temp_dir = TempDir::new().unwrap();
let config = CacheConfig {
cache_dir: temp_dir.path().to_path_buf(),
enabled: true,
max_age_secs: None,
};
let cached = read_cache("nonexistent", &[], &config).unwrap();
assert!(cached.is_none());
}
#[test]
fn test_cache_disabled() {
let temp_dir = TempDir::new().unwrap();
let config = CacheConfig {
cache_dir: temp_dir.path().to_path_buf(),
enabled: false,
max_age_secs: None,
};
let result = ProbeResult {
command: "test-cmd".to_string(),
args: vec![],
exit_code: Some(0),
timed_out: false,
help_flag_detected: true,
usage_blocks: vec![],
options: vec![],
subcommands: vec![],
arguments: vec![],
examples: vec![],
environment_variables: vec![],
validation_rules: vec![],
raw_stdout: String::new(),
raw_stderr: String::new(),
};
write_cache("test-cmd", &[], &result, &config).unwrap();
let cached = read_cache("test-cmd", &[], &config).unwrap();
assert!(cached.is_none());
}
#[test]
fn test_default_cache_dir() {
use help_probe::cache::default_cache_dir;
let dir = default_cache_dir();
assert!(dir.to_string_lossy().contains("cache"));
assert!(dir.to_string_lossy().contains("help-probe"));
}
#[test]
fn test_cache_expiration() {
use std::time::Duration;
let temp_dir = TempDir::new().unwrap();
let config = CacheConfig {
cache_dir: temp_dir.path().to_path_buf(),
enabled: true,
max_age_secs: Some(1), };
let result = ProbeResult {
command: "test-cmd".to_string(),
args: vec!["--help".to_string()],
exit_code: Some(0),
timed_out: false,
help_flag_detected: true,
usage_blocks: vec![],
options: vec![],
subcommands: vec![],
arguments: vec![],
examples: vec![],
environment_variables: vec![],
validation_rules: vec![],
raw_stdout: "test output".to_string(),
raw_stderr: String::new(),
};
write_cache("test-cmd", &["--help".to_string()], &result, &config).unwrap();
let cached = read_cache("test-cmd", &["--help".to_string()], &config).unwrap();
assert!(cached.is_some());
std::thread::sleep(Duration::from_secs(2));
let cached = read_cache("test-cmd", &["--help".to_string()], &config).unwrap();
assert!(cached.is_none());
}
#[test]
fn test_cache_version_change() {
let temp_dir = TempDir::new().unwrap();
let config = CacheConfig {
cache_dir: temp_dir.path().to_path_buf(),
enabled: true,
max_age_secs: None,
};
let result1 = ProbeResult {
command: "test-cmd".to_string(),
args: vec!["--help".to_string()],
exit_code: Some(0),
timed_out: false,
help_flag_detected: true,
usage_blocks: vec![],
options: vec![],
subcommands: vec![],
arguments: vec![],
examples: vec![],
environment_variables: vec![],
validation_rules: vec![],
raw_stdout: "version 1".to_string(),
raw_stderr: String::new(),
};
write_cache("test-cmd", &["--help".to_string()], &result1, &config).unwrap();
let cached = read_cache("test-cmd", &["--help".to_string()], &config).unwrap();
assert!(cached.is_some());
let result2 = ProbeResult {
command: "test-cmd".to_string(),
args: vec!["--help".to_string()],
exit_code: Some(0),
timed_out: false,
help_flag_detected: true,
usage_blocks: vec![],
options: vec![],
subcommands: vec![],
arguments: vec![],
examples: vec![],
environment_variables: vec![],
validation_rules: vec![],
raw_stdout: "version 2 - different".to_string(),
raw_stderr: String::new(),
};
write_cache("test-cmd", &["--help".to_string()], &result2, &config).unwrap();
let cached = read_cache("test-cmd", &["--help".to_string()], &config).unwrap();
assert!(cached.is_some());
assert_eq!(cached.unwrap().raw_stdout, "version 2 - different");
}
#[test]
fn test_clear_cache() {
use help_probe::cache::clear_cache;
let temp_dir = TempDir::new().unwrap();
let config = CacheConfig {
cache_dir: temp_dir.path().to_path_buf(),
enabled: true,
max_age_secs: None,
};
let result = ProbeResult {
command: "test-cmd".to_string(),
args: vec!["--help".to_string()],
exit_code: Some(0),
timed_out: false,
help_flag_detected: true,
usage_blocks: vec![],
options: vec![],
subcommands: vec![],
arguments: vec![],
examples: vec![],
environment_variables: vec![],
validation_rules: vec![],
raw_stdout: "test output".to_string(),
raw_stderr: String::new(),
};
write_cache("test-cmd", &["--help".to_string()], &result, &config).unwrap();
let cached = read_cache("test-cmd", &["--help".to_string()], &config).unwrap();
assert!(cached.is_some());
let cleared = clear_cache(Some("test-cmd"), Some(&["--help".to_string()]), &config).unwrap();
assert_eq!(cleared, 1);
let cached = read_cache("test-cmd", &["--help".to_string()], &config).unwrap();
assert!(cached.is_none());
}
#[test]
fn test_clear_all_cache() {
use help_probe::cache::clear_cache;
let temp_dir = TempDir::new().unwrap();
let config = CacheConfig {
cache_dir: temp_dir.path().to_path_buf(),
enabled: true,
max_age_secs: None,
};
let result1 = ProbeResult {
command: "cmd1".to_string(),
args: vec![],
exit_code: Some(0),
timed_out: false,
help_flag_detected: true,
usage_blocks: vec![],
options: vec![],
subcommands: vec![],
arguments: vec![],
examples: vec![],
environment_variables: vec![],
validation_rules: vec![],
raw_stdout: "output1".to_string(),
raw_stderr: String::new(),
};
let result2 = ProbeResult {
command: "cmd2".to_string(),
args: vec![],
exit_code: Some(0),
timed_out: false,
help_flag_detected: true,
usage_blocks: vec![],
options: vec![],
subcommands: vec![],
arguments: vec![],
examples: vec![],
environment_variables: vec![],
validation_rules: vec![],
raw_stdout: "output2".to_string(),
raw_stderr: String::new(),
};
write_cache("cmd1", &[], &result1, &config).unwrap();
write_cache("cmd2", &[], &result2, &config).unwrap();
let cleared = clear_cache(None, None, &config).unwrap();
assert!(cleared >= 2);
let cached1 = read_cache("cmd1", &[], &config).unwrap();
let cached2 = read_cache("cmd2", &[], &config).unwrap();
assert!(cached1.is_none());
assert!(cached2.is_none());
}