use super::*;
use crate::core::data_dir::isolated_data_dir;
#[test]
fn load_honors_content_change_with_preserved_mtime() {
let _iso = isolated_data_dir();
let path = Config::path().expect("config path under isolated data dir");
if let Some(parent) = path.parent() {
std::fs::create_dir_all(parent).unwrap();
}
std::fs::write(&path, "# initial\n").unwrap();
let mtime0 = std::fs::metadata(&path).unwrap().modified().unwrap();
assert_eq!(Config::load().path_jail, None);
std::fs::write(&path, "path_jail = false\n").unwrap();
filetime::set_file_mtime(&path, filetime::FileTime::from_system_time(mtime0)).unwrap();
assert_eq!(
Config::load().path_jail,
Some(false),
"Config::load() must honor a content change with unchanged mtime (#406)"
);
}
#[test]
fn load_inside_a_request_merges_that_projects_local_config() {
let _iso = isolated_data_dir();
let projects = [tempfile::tempdir().unwrap(), tempfile::tempdir().unwrap()];
for (project, command) in projects.iter().zip(["ap04-first", "ap04-second"]) {
std::fs::write(
project.path().join(".lean-ctx.toml"),
format!("excluded_commands = [\"{command}\"]\n"),
)
.unwrap();
}
let excluded = |project: &tempfile::TempDir| {
crate::core::policy::runtime::REQUEST_PROJECT.sync_scope(
std::cell::RefCell::new(Some(project.path().to_path_buf())),
|| Config::load().excluded_commands,
)
};
assert!(excluded(&projects[0]).contains(&"ap04-first".to_string()));
let second = excluded(&projects[1]);
assert!(second.contains(&"ap04-second".to_string()));
assert!(!second.contains(&"ap04-first".to_string()));
}
#[test]
fn trust_of_one_project_is_not_reused_for_an_identical_local_config() {
let _iso = isolated_data_dir();
let extra = tempfile::tempdir().unwrap();
let extra_root = extra.path().to_string_lossy().to_string();
let projects = [tempfile::tempdir().unwrap(), tempfile::tempdir().unwrap()];
for project in &projects {
std::fs::write(
project.path().join(".lean-ctx.toml"),
format!("extra_roots = [{extra_root:?}]\n"),
)
.unwrap();
}
crate::core::workspace_trust::trust(projects[0].path()).expect("trust the first project");
let extra_roots = |project: &tempfile::TempDir| {
crate::core::policy::runtime::REQUEST_PROJECT.sync_scope(
std::cell::RefCell::new(Some(project.path().to_path_buf())),
|| Config::load().extra_roots,
)
};
assert!(extra_roots(&projects[0]).contains(&extra_root));
assert!(!extra_roots(&projects[1]).contains(&extra_root));
}
#[test]
fn a_background_thread_of_a_request_reads_its_projects_config() {
let _iso = isolated_data_dir();
let path = Config::path().expect("config path under isolated data dir");
std::fs::create_dir_all(path.parent().unwrap()).unwrap();
std::fs::write(&path, "auto_capture = true\n").unwrap();
let project = tempfile::tempdir().unwrap();
std::fs::write(
project.path().join(".lean-ctx.toml"),
"auto_capture = false\n",
)
.unwrap();
let in_thread = crate::core::policy::runtime::spawn_for_project(project.path(), || {
Config::load().auto_capture
})
.join()
.unwrap();
assert!(!in_thread);
}
#[test]
fn load_arc_follows_trust_changes_without_a_file_change() {
let _iso = isolated_data_dir();
let path = Config::path().expect("config path under isolated data dir");
if let Some(parent) = path.parent() {
std::fs::create_dir_all(parent).unwrap();
}
std::fs::write(&path, "# global\n").unwrap();
let project = tempfile::tempdir().unwrap();
std::fs::write(
Config::local_path(project.path().to_str().unwrap()),
"shell_allowlist = [\"git\"]\n",
)
.unwrap();
let root_str = project.path().to_string_lossy().into_owned();
let root = Some(root_str.as_str());
let cache = std::sync::Mutex::new(None);
let narrow = vec!["git".to_string()];
let untrusted = Config::load_arc_with(root, &cache);
assert_ne!(
untrusted.shell_allowlist, narrow,
"untrusted: override withheld"
);
crate::core::workspace_trust::trust(project.path()).unwrap();
let trusted = Config::load_arc_with(root, &cache);
assert_eq!(
trusted.shell_allowlist, narrow,
"trust must reach a warm cache"
);
crate::core::workspace_trust::untrust(project.path()).unwrap();
let revoked = Config::load_arc_with(root, &cache);
assert_ne!(
revoked.shell_allowlist, narrow,
"untrust must reach a warm cache"
);
}