#![cfg(all(feature = "embedded", unix))]
use std::path::{Path, PathBuf};
use std::process::{Command, Output, Stdio};
fn scratch(case: &str) -> PathBuf {
let dir = std::env::temp_dir().join(format!("iki-fr-{}-{case}", std::process::id()));
let _ = std::fs::remove_dir_all(&dir);
std::fs::create_dir_all(dir.join("config").join("ikigai")).expect("scratch config home");
for root in [
"flag",
"config/ikigai/scoped",
"config/ikigai/plain",
"env",
".ikigai/workspace",
] {
let at = dir.join(root);
std::fs::create_dir_all(&at).expect("a candidate root");
std::fs::write(at.join("which.txt"), root).expect("its marker");
}
dir
}
fn config(home: &Path, text: &str) {
std::fs::write(home.join("config/ikigai/config.toml"), text).expect("config.toml");
}
fn which(home: &Path, flags: &[&str], env: bool) -> String {
let mut command = Command::new(env!("CARGO_BIN_EXE_ikigai"));
command
.args(flags)
.args(["--no-config-mounts", "-c", "source urn:file:which.txt"])
.current_dir(home)
.env("HOME", home)
.env("XDG_CONFIG_HOME", home.join("config"))
.stdin(Stdio::null());
if env {
command.env("IKIGAI_FILES", home.join("env"));
} else {
command.env_remove("IKIGAI_FILES");
}
let out: Output = command.output().expect("the binary runs");
assert!(
out.status.success(),
"{flags:?}: {}",
String::from_utf8_lossy(&out.stderr)
);
String::from_utf8_lossy(&out.stdout).trim().to_string()
}
#[test]
fn the_flag_then_the_config_home_then_the_variable_then_the_default() {
let home = scratch("order");
let flag = home.join("flag");
let flag = flag.to_str().unwrap();
config(&home, "repl.files = \"scoped\"\nfiles = \"plain\"\n");
assert_eq!(
which(&home, &["--files", flag], true),
"flag",
"the flag wins"
);
assert_eq!(
which(&home, &["--files=flag"], true),
"flag",
"relative to the working directory"
);
assert_eq!(
which(&home, &[], true),
"config/ikigai/scoped",
"then the instance-scoped key, relative to the config home"
);
assert_eq!(
which(&home, &["--name", "other"], true),
"config/ikigai/plain",
"an instance the scoped key does not name reads the plain key"
);
config(&home, "");
assert_eq!(
which(&home, &[], true),
"env",
"then IKIGAI_FILES, kept as the fallback"
);
assert_eq!(
which(&home, &[], false),
".ikigai/workspace",
"then the default under the data home"
);
let _ = std::fs::remove_dir_all(&home);
}
#[test]
fn files_beside_connect_is_refused() {
let home = scratch("connect");
let out = Command::new(env!("CARGO_BIN_EXE_ikigai"))
.args([
"--files",
"/tmp",
"--connect",
"/tmp/nothing.sock",
"-c",
"list",
])
.env("HOME", &home)
.env("XDG_CONFIG_HOME", home.join("config"))
.stdin(Stdio::null())
.output()
.expect("the binary runs");
let stderr = String::from_utf8_lossy(&out.stderr);
assert!(
!out.status.success() && stderr.contains("--files") && stderr.contains("--connect"),
"{stderr}"
);
let _ = std::fs::remove_dir_all(&home);
}