use crate::{app_path, try_app_path, AppPath};
use std::env;
use std::path::PathBuf;
#[test]
fn test_app_path_macro_no_params() {
let app_base = app_path!();
assert!(app_base.is_absolute());
let current_exe = std::env::current_exe().unwrap();
let exe_parent = current_exe.parent().unwrap();
assert_eq!(&*app_base, exe_parent);
let app_base2 = app_path!();
assert_eq!(app_base, app_base2);
assert!(app_base.is_dir());
}
#[test]
fn test_app_path_macro_basic() {
let config = app_path!("config.toml");
let expected = AppPath::with("config.toml");
assert_eq!(config, expected);
}
#[test]
fn test_app_path_macro_with_env() {
let temp_dir = env::temp_dir();
let custom_path = temp_dir.join("custom_config.toml");
env::set_var("TEST_CONFIG_PATH", &custom_path);
let config = app_path!("default.toml", env = "TEST_CONFIG_PATH");
assert_eq!(&*config, &custom_path);
let default_config = app_path!("default.toml", env = "NON_EXISTENT_VAR");
let expected = std::env::current_exe()
.unwrap()
.parent()
.unwrap()
.join("default.toml");
assert_eq!(&*default_config, &expected);
env::remove_var("TEST_CONFIG_PATH");
}
#[test]
fn test_app_path_macro_with_override() {
let temp_dir = env::temp_dir();
let override_path = temp_dir.join("custom_path.toml");
let config = app_path!("default.toml", override = Some(override_path.clone()));
assert_eq!(&*config, &override_path);
let no_override: Option<PathBuf> = None;
let default_config = app_path!("default.toml", override = no_override);
let expected = std::env::current_exe()
.unwrap()
.parent()
.unwrap()
.join("default.toml");
assert_eq!(&*default_config, &expected);
}
#[test]
fn test_app_path_macro_with_fn() {
let custom_path = env::temp_dir().join("custom_fn.toml");
let config = app_path!("default.toml", fn = || Some(custom_path.clone()));
assert_eq!(&*config, &custom_path);
let default_config = app_path!("default.toml", fn = || None::<PathBuf>);
let expected = std::env::current_exe()
.unwrap()
.parent()
.unwrap()
.join("default.toml");
assert_eq!(&*default_config, &expected);
let complex_config = app_path!("config.toml", fn = || {
if env::var("USE_CUSTOM_CONFIG").is_ok() {
Some(env::temp_dir().join("custom.toml"))
} else {
None
}
});
let expected_complex = std::env::current_exe()
.unwrap()
.parent()
.unwrap()
.join("config.toml");
assert_eq!(&*complex_config, &expected_complex);
}
#[test]
fn test_try_app_path_macro_no_params() {
let result = try_app_path!();
assert!(result.is_ok());
let app_base = result.unwrap();
assert!(app_base.is_absolute());
let current_exe = std::env::current_exe().unwrap();
let exe_parent = current_exe.parent().unwrap();
assert_eq!(&*app_base, exe_parent);
let panicking_version = app_path!();
assert_eq!(app_base, panicking_version);
assert!(app_base.is_dir());
}
#[test]
fn test_try_app_path_macro_basic() {
let config = try_app_path!("config.toml").unwrap();
let expected = AppPath::try_with("config.toml").unwrap();
assert_eq!(config, expected);
}
#[test]
fn test_try_app_path_macro_with_env() {
let temp_dir = env::temp_dir();
let custom_path = temp_dir.join("custom_config.toml");
env::set_var("TEST_TRY_CONFIG_PATH", &custom_path);
let config = try_app_path!("default.toml", env = "TEST_TRY_CONFIG_PATH").unwrap();
assert_eq!(&*config, &custom_path);
let default_config = try_app_path!("default.toml", env = "NON_EXISTENT_VAR").unwrap();
let expected = std::env::current_exe()
.unwrap()
.parent()
.unwrap()
.join("default.toml");
assert_eq!(&*default_config, &expected);
env::remove_var("TEST_TRY_CONFIG_PATH");
}
#[test]
fn test_try_app_path_macro_with_override() {
let temp_dir = env::temp_dir();
let override_path = temp_dir.join("custom_path.toml");
let config = try_app_path!("default.toml", override = Some(override_path.clone())).unwrap();
assert_eq!(&*config, &override_path);
let no_override: Option<PathBuf> = None;
let default_config = try_app_path!("default.toml", override = no_override).unwrap();
let expected = std::env::current_exe()
.unwrap()
.parent()
.unwrap()
.join("default.toml");
assert_eq!(&*default_config, &expected);
}
#[test]
fn test_try_app_path_macro_with_fn() {
let custom_path = env::temp_dir().join("custom_fn.toml");
let config = try_app_path!("default.toml", fn = || Some(custom_path.clone())).unwrap();
assert_eq!(&*config, &custom_path);
let default_config = try_app_path!("default.toml", fn = || None::<PathBuf>).unwrap();
let expected = std::env::current_exe()
.unwrap()
.parent()
.unwrap()
.join("default.toml");
assert_eq!(&*default_config, &expected);
let complex_config = try_app_path!("config.toml", fn = || {
if env::var("USE_CUSTOM_TRY_CONFIG").is_ok() {
Some(env::temp_dir().join("custom_try.toml"))
} else {
None
}
})
.unwrap();
let expected_complex = std::env::current_exe()
.unwrap()
.parent()
.unwrap()
.join("config.toml");
assert_eq!(&*complex_config, &expected_complex);
}
#[test]
fn test_try_app_path_macro_returns_result() {
let result = try_app_path!("test.toml");
assert!(result.is_ok());
match try_app_path!("test.toml") {
Ok(path) => {
assert!(path.ends_with("test.toml"));
}
Err(_) => panic!("Should not fail in normal conditions"),
}
}
#[test]
fn test_try_app_path_vs_app_path_equivalence() {
let panicking = app_path!("config.toml");
let fallible = try_app_path!("config.toml").unwrap();
assert_eq!(panicking, fallible);
env::set_var("TEST_EQUIV_PATH", "/tmp/test.conf");
let panicking_env = app_path!("default.conf", env = "TEST_EQUIV_PATH");
let fallible_env = try_app_path!("default.conf", env = "TEST_EQUIV_PATH").unwrap();
assert_eq!(panicking_env, fallible_env);
env::remove_var("TEST_EQUIV_PATH");
let override_path = Some(PathBuf::from("/custom/path.conf"));
let panicking_override = app_path!("default.conf", override = override_path.clone());
let fallible_override = try_app_path!("default.conf", override = override_path).unwrap();
assert_eq!(panicking_override, fallible_override);
}
#[test]
fn test_macro_fn_variants_equivalence() {
let panicking_fn = app_path!("test.toml", fn = || None::<String>);
let fallible_fn = try_app_path!("test.toml", fn = || None::<String>).unwrap();
assert_eq!(panicking_fn, fallible_fn);
let custom_path = env::temp_dir().join("equiv_test.toml");
let panicking_fn_some = app_path!("test.toml", fn = || Some(custom_path.clone()));
let fallible_fn_some = try_app_path!("test.toml", fn = || Some(custom_path.clone())).unwrap();
assert_eq!(panicking_fn_some, fallible_fn_some);
}
#[test]
fn test_fn_variant_with_real_xdg_logic() {
fn get_config_path() -> Option<PathBuf> {
env::var("XDG_CONFIG_HOME")
.or_else(|_| env::var("HOME").map(|h| format!("{h}/.config")))
.ok()
.map(|config_dir| PathBuf::from(config_dir).join("myapp"))
}
let config_app_path = app_path!("config.toml", fn = get_config_path);
let config_try_app_path = try_app_path!("config.toml", fn = get_config_path).unwrap();
assert_eq!(config_app_path, config_try_app_path);
if env::var("XDG_CONFIG_HOME").is_ok() || env::var("HOME").is_ok() {
let xdg_result = get_config_path();
if let Some(xdg_path) = xdg_result {
assert_eq!(&*config_app_path, &xdg_path);
}
} else {
let expected = std::env::current_exe()
.unwrap()
.parent()
.unwrap()
.join("config.toml");
assert_eq!(&*config_app_path, &expected);
}
}