use dotcfg::DotCfg;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug, PartialEq, Default)]
struct TestConfig {
username: String,
port: u16,
#[serde(default)]
nested: Option<Nested>,
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Default)]
struct Nested {
val: String,
}
#[cfg(feature = "toml")]
const DEFAULT_EXT: &str = "toml";
#[cfg(all(feature = "json", not(feature = "toml")))]
const DEFAULT_EXT: &str = "json";
#[cfg(all(feature = "yaml", not(feature = "toml"), not(feature = "json")))]
const DEFAULT_EXT: &str = "yaml";
use std::path::PathBuf;
fn temp_custom_dir(suffix: &str) -> PathBuf {
let path = std::env::temp_dir().join(format!(
"dotcfg_test_custom_{}_{}_{}",
suffix,
std::process::id(),
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_nanos()
));
let _ = std::fs::remove_dir_all(&path);
path
}
#[test]
fn custom_dir_isolated_temp_dir() {
let dir = temp_custom_dir("isolated");
let cfg = DotCfg::new("ignored_app_name").at_dir(&dir);
assert_eq!(cfg.dir().unwrap(), dir);
assert_eq!(
cfg.file_path().unwrap(),
dir.join(format!("config.{}", DEFAULT_EXT))
);
let original = TestConfig {
username: "tayo".into(),
port: 8080,
nested: None,
};
cfg.save(&original).unwrap();
assert!(cfg.exists().unwrap());
let loaded: Option<TestConfig> = cfg.load().unwrap();
assert_eq!(loaded, Some(original));
cfg.set("username", "jane").unwrap();
assert_eq!(cfg.get("username").unwrap(), "jane");
cfg.set_val("port", 9090u16).unwrap();
assert_eq!(cfg.get_as::<u16>("port").unwrap(), 9090);
cfg.delete_dir().unwrap();
assert!(!dir.exists());
}
#[test]
fn custom_dir_flexible_any_name() {
for name in [".sendra", ".nottoolname", "my-config"] {
let base = temp_custom_dir(&format!("flex_{}", name.replace('.', "_")));
let dir = base.join(name);
let cfg = DotCfg::new("mytool").at_dir(&dir);
cfg.set("username", "tayo").unwrap();
assert_eq!(cfg.get("username").unwrap(), "tayo");
assert_eq!(cfg.dir().unwrap(), dir);
cfg.delete_dir().unwrap();
}
}
#[test]
fn custom_dir_relative_dot_dir() {
let dir = temp_custom_dir("relative");
std::fs::create_dir_all(&dir).unwrap();
let dot_dir = dir.join(".sendra");
let cfg = DotCfg::new("sendra").at_dir(&dot_dir);
cfg.set("username", "alice").unwrap();
assert_eq!(cfg.get("username").unwrap(), "alice");
assert!(dot_dir.exists());
cfg.delete_dir().unwrap();
let _ = std::fs::remove_dir_all(&dir);
}