use std::path::PathBuf;
use super::index::ensure_memory_index;
use super::paths::encode_project_path;
use super::runtime::{enforce_native_memory_limit, env_value_enabled};
fn unique_temp_dir(name: &str) -> PathBuf {
let nanos = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.expect("clock should be after unix epoch")
.as_nanos();
std::env::temp_dir().join(format!("remem-{}-{}-{}", name, std::process::id(), nanos))
}
#[test]
fn encode_project_path_replaces_slashes_after_canonicalize() {
let dir = unique_temp_dir("claude-memory-path");
std::fs::create_dir_all(&dir).expect("temp dir should create");
let encoded = encode_project_path(dir.to_str().expect("temp path should be utf-8"));
let canonical =
crate::db::canonical_project_path(dir.to_str().expect("temp path should be utf-8"));
let expected = canonical.to_string_lossy().replace('/', "-");
assert_eq!(encoded, expected);
std::fs::remove_dir_all(&dir).expect("temp dir should clean up");
}
#[test]
fn ensure_memory_index_is_idempotent() {
let dir = unique_temp_dir("claude-memory-index-idempotent");
std::fs::create_dir_all(&dir).expect("temp dir should create");
let index_path = dir.join("MEMORY.md");
std::fs::write(&index_path, "# Memory Index\n").expect("index should write");
ensure_memory_index(&dir).expect("first ensure should succeed");
ensure_memory_index(&dir).expect("second ensure should succeed");
let content = std::fs::read_to_string(&index_path).expect("index should read");
assert_eq!(content.matches("remem_sessions.md").count(), 1);
std::fs::remove_dir_all(&dir).expect("temp dir should clean up");
}
#[test]
fn ensure_memory_index_creates_new_file_when_missing() {
let dir = unique_temp_dir("claude-memory-index-create");
std::fs::create_dir_all(&dir).expect("temp dir should create");
ensure_memory_index(&dir).expect("ensure should succeed");
let content = std::fs::read_to_string(dir.join("MEMORY.md")).expect("index should read");
assert!(content.contains("# Memory Index"));
assert!(content.contains("remem_sessions.md"));
std::fs::remove_dir_all(&dir).expect("temp dir should clean up");
}
#[test]
fn native_memory_limit_caps_output_without_breaking_utf8() {
let content = format!(
"---\nname: remem_sessions\n---\n\n{}\n",
"关键决策和最近会话摘要".repeat(80)
);
let (capped, truncated) = enforce_native_memory_limit(&content, 512);
assert!(truncated);
assert!(capped.len() <= 512, "capped length was {}", capped.len());
assert!(capped.is_char_boundary(capped.len()));
assert!(capped.contains("Truncated by remem native memory guard"));
}
#[test]
fn native_memory_disable_env_accepts_explicit_truthy_values() {
for value in ["1", "true", "TRUE", "yes", "on"] {
assert!(env_value_enabled(value), "{value}");
}
for value in ["", "0", "false", "off", "disabled"] {
assert!(!env_value_enabled(value), "{value}");
}
}