use assert_cmd::Command;
use predicates::prelude::*;
use std::fs;
use std::thread;
use std::time::Duration;
use tempfile::TempDir;
#[test]
fn test_cache_basic_reuse() {
let temp_dir = TempDir::new().unwrap();
let file_path = temp_dir.path().join("test.ts");
fs::write(&file_path, "function test() { return 42; }").unwrap();
let output1 = Command::cargo_bin("skim")
.unwrap()
.arg(&file_path)
.assert()
.success()
.get_output()
.stdout
.clone();
let output2 = Command::cargo_bin("skim")
.unwrap()
.arg(&file_path)
.assert()
.success()
.get_output()
.stdout
.clone();
assert_eq!(output1, output2, "Cached output should match original");
}
#[test]
fn test_cache_invalidation_on_file_modification() {
let temp_dir = TempDir::new().unwrap();
let file_path = temp_dir.path().join("test.ts");
fs::write(&file_path, "function original() { return 1; }").unwrap();
Command::cargo_bin("skim")
.unwrap()
.arg(&file_path)
.assert()
.success()
.stdout(predicate::str::contains("function original"));
thread::sleep(Duration::from_secs(1));
fs::write(&file_path, "function modified() { return 2; }").unwrap();
Command::cargo_bin("skim")
.unwrap()
.arg(&file_path)
.assert()
.success()
.stdout(predicate::str::contains("function modified"))
.stdout(predicate::str::contains("function original").not());
}
#[test]
fn test_cache_different_modes() {
let temp_dir = TempDir::new().unwrap();
let file_path = temp_dir.path().join("test.ts");
fs::write(&file_path, "function test() { return 42; }").unwrap();
let structure_output = Command::cargo_bin("skim")
.unwrap()
.arg(&file_path)
.arg("--mode=structure")
.assert()
.success()
.get_output()
.stdout
.clone();
let signatures_output = Command::cargo_bin("skim")
.unwrap()
.arg(&file_path)
.arg("--mode=signatures")
.assert()
.success()
.get_output()
.stdout
.clone();
assert_ne!(
structure_output, signatures_output,
"Different modes should produce different output"
);
}
#[test]
fn test_no_cache_flag() {
let temp_dir = TempDir::new().unwrap();
let file_path = temp_dir.path().join("test.ts");
fs::write(&file_path, "function test() { return 42; }").unwrap();
let output1 = Command::cargo_bin("skim")
.unwrap()
.arg(&file_path)
.arg("--no-cache")
.assert()
.success()
.get_output()
.stdout
.clone();
let output2 = Command::cargo_bin("skim")
.unwrap()
.arg(&file_path)
.arg("--no-cache")
.assert()
.success()
.get_output()
.stdout
.clone();
assert_eq!(output1, output2);
Command::cargo_bin("skim")
.unwrap()
.arg(&file_path)
.assert()
.success();
}
#[test]
fn test_clear_cache_command() {
let temp_dir = TempDir::new().unwrap();
let file_path = temp_dir.path().join("test.ts");
fs::write(&file_path, "function test() { return 42; }").unwrap();
Command::cargo_bin("skim")
.unwrap()
.arg(&file_path)
.assert()
.success();
Command::cargo_bin("skim")
.unwrap()
.arg("--clear-cache")
.assert()
.success()
.stdout(predicate::str::contains("Cache cleared successfully"));
Command::cargo_bin("skim")
.unwrap()
.arg(&file_path)
.assert()
.success();
}
#[test]
fn test_cache_with_glob_patterns() {
let temp_dir = TempDir::new().unwrap();
fs::write(temp_dir.path().join("file1.ts"), "function a() {}").unwrap();
fs::write(temp_dir.path().join("file2.ts"), "function b() {}").unwrap();
fs::write(temp_dir.path().join("file3.ts"), "function c() {}").unwrap();
let output1 = Command::cargo_bin("skim")
.unwrap()
.arg("*.ts")
.current_dir(temp_dir.path())
.assert()
.success()
.get_output()
.stdout
.clone();
let output2 = Command::cargo_bin("skim")
.unwrap()
.arg("*.ts")
.current_dir(temp_dir.path())
.assert()
.success()
.get_output()
.stdout
.clone();
assert_eq!(output1, output2, "Cached glob output should match original");
}
#[test]
fn test_cache_stores_token_counts() {
let temp_dir = TempDir::new().unwrap();
let file_path = temp_dir.path().join("test.ts");
fs::write(&file_path, "function test() { return 42; }").unwrap();
let stderr1 = Command::cargo_bin("skim")
.unwrap()
.arg(&file_path)
.arg("--show-stats")
.assert()
.success()
.get_output()
.stderr
.clone();
let stderr1_str = String::from_utf8_lossy(&stderr1);
assert!(
stderr1_str.contains("[skim]"),
"First run should show token stats"
);
let stderr2 = Command::cargo_bin("skim")
.unwrap()
.arg(&file_path)
.arg("--show-stats")
.assert()
.success()
.get_output()
.stderr
.clone();
let stderr2_str = String::from_utf8_lossy(&stderr2);
assert!(
stderr2_str.contains("[skim]"),
"Second run should show cached token stats"
);
assert_eq!(
stderr1_str, stderr2_str,
"Cached token counts should match original"
);
}
#[test]
fn test_cache_with_explicit_language() {
let temp_dir = TempDir::new().unwrap();
let file_path = temp_dir.path().join("noext");
fs::write(&file_path, "function test() { return 42; }").unwrap();
let output1 = Command::cargo_bin("skim")
.unwrap()
.arg(&file_path)
.arg("--language=typescript")
.assert()
.success()
.get_output()
.stdout
.clone();
let output2 = Command::cargo_bin("skim")
.unwrap()
.arg(&file_path)
.arg("--language=typescript")
.assert()
.success()
.get_output()
.stdout
.clone();
assert_eq!(output1, output2);
}
#[test]
fn test_no_cache_with_show_stats() {
let temp_dir = TempDir::new().unwrap();
let file_path = temp_dir.path().join("test.ts");
fs::write(&file_path, "function test() { return 42; }").unwrap();
Command::cargo_bin("skim")
.unwrap()
.arg(&file_path)
.arg("--no-cache")
.arg("--show-stats")
.assert()
.success()
.stderr(predicate::str::contains("[skim]"));
}
#[test]
fn test_cache_stats_computed_on_hit_when_missing() {
let temp_dir = TempDir::new().unwrap();
let file_path = temp_dir.path().join("test.ts");
fs::write(&file_path, "function test() { return 42; }").unwrap();
Command::cargo_bin("skim")
.unwrap()
.arg(&file_path)
.assert()
.success();
Command::cargo_bin("skim")
.unwrap()
.arg(&file_path)
.arg("--show-stats")
.assert()
.success()
.stderr(predicate::str::contains("[skim]"));
}