use crate::{app_path, try_app_path};
use std::env;
use std::path::PathBuf;
#[test]
fn test_env_override_with_string() {
let temp_dir = env::temp_dir();
let custom_path = temp_dir.join("env_override.toml");
env::set_var("TEST_ENV_OVERRIDE", &custom_path);
let config = app_path!("default.toml", env = "TEST_ENV_OVERRIDE");
assert_eq!(&*config, custom_path.as_path());
env::remove_var("TEST_ENV_OVERRIDE");
}
#[test]
fn test_env_override_with_nonexistent_var() {
let config = app_path!("default.toml", env = "DEFINITELY_NONEXISTENT_VAR");
let expected = std::env::current_exe()
.unwrap()
.parent()
.unwrap()
.join("default.toml");
assert_eq!(&*config, expected.as_path());
}
#[test]
fn test_env_override_empty_value() {
env::set_var("EMPTY_ENV_VAR", "");
let config = app_path!("default.toml", env = "EMPTY_ENV_VAR");
let expected_path = config.to_path_buf();
assert!(expected_path.to_string_lossy().contains("target"));
assert!(
config.is_dir()
|| config
.to_string_lossy()
.ends_with(std::path::MAIN_SEPARATOR)
);
env::remove_var("EMPTY_ENV_VAR");
}
#[test]
fn test_env_override_relative_path() {
env::set_var("RELATIVE_PATH_VAR", "config/test.toml");
let config = app_path!("default.toml", env = "RELATIVE_PATH_VAR");
let expected = std::env::current_exe()
.unwrap()
.parent()
.unwrap()
.join("config/test.toml");
assert_eq!(&*config, &expected);
env::remove_var("RELATIVE_PATH_VAR");
}
#[test]
fn test_env_override_absolute_path() {
let temp_dir = env::temp_dir();
let absolute_path = temp_dir.join("absolute_test.toml");
env::set_var("ABSOLUTE_PATH_VAR", &absolute_path);
let config = app_path!("default.toml", env = "ABSOLUTE_PATH_VAR");
assert_eq!(&*config, &absolute_path);
env::remove_var("ABSOLUTE_PATH_VAR");
}
#[test]
fn test_direct_override_with_some_pathbuf() {
let override_path = if cfg!(windows) {
PathBuf::from("C:\\custom\\override\\path.toml")
} else {
PathBuf::from("/custom/override/path.toml")
};
let config = app_path!("default.toml", override = Some(override_path.clone()));
assert_eq!(&*config, &override_path);
}
#[test]
fn test_direct_override_with_some_string() {
let override_path = if cfg!(windows) {
Some("C:\\custom\\override\\string.toml")
} else {
Some("/custom/override/string.toml")
};
let config = app_path!("default.toml", override = override_path);
let expected = if cfg!(windows) {
PathBuf::from("C:\\custom\\override\\string.toml")
} else {
PathBuf::from("/custom/override/string.toml")
};
assert_eq!(&*config, &expected);
}
#[test]
fn test_direct_override_with_none() {
let override_path: Option<PathBuf> = None;
let config = app_path!("default.toml", override = override_path);
let expected = std::env::current_exe()
.unwrap()
.parent()
.unwrap()
.join("default.toml");
assert_eq!(&*config, &expected);
}
#[test]
fn test_direct_override_with_variable() {
let temp_dir = env::temp_dir();
let custom_path = temp_dir.join("variable_override.toml");
let maybe_override = Some(custom_path.clone());
let config = app_path!("default.toml", override = maybe_override);
assert_eq!(&*config, &custom_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_fn_override_returning_some() {
let custom_path = env::temp_dir().join("fn_override.toml");
let config = app_path!("default.toml", fn = || Some(custom_path.clone()));
assert_eq!(&*config, &custom_path);
}
#[test]
fn test_fn_override_returning_none() {
let config = app_path!("default.toml", fn = || None::<PathBuf>);
let expected = std::env::current_exe()
.unwrap()
.parent()
.unwrap()
.join("default.toml");
assert_eq!(&*config, &expected);
}
#[test]
fn test_fn_override_with_conditional_logic() {
let config = app_path!("config.toml", fn = || {
if env::var("USE_TEMP_CONFIG").is_ok() {
Some(env::temp_dir().join("temp_config.toml"))
} else {
None
}
});
let expected = std::env::current_exe()
.unwrap()
.parent()
.unwrap()
.join("config.toml");
assert_eq!(&*config, &expected);
env::set_var("USE_TEMP_CONFIG", "1");
let config_with_env = app_path!("config.toml", fn = || {
if env::var("USE_TEMP_CONFIG").is_ok() {
Some(env::temp_dir().join("temp_config.toml"))
} else {
None
}
});
let expected_temp = env::temp_dir().join("temp_config.toml");
assert_eq!(&*config_with_env, &expected_temp);
env::remove_var("USE_TEMP_CONFIG");
}
#[test]
fn test_fn_override_with_xdg_style_logic() {
fn get_xdg_config_path() -> Option<PathBuf> {
env::var("XDG_CONFIG_HOME")
.or_else(|_| env::var("HOME").map(|h| format!("{h}/.config")))
.ok()
.map(|base| PathBuf::from(base).join("myapp").join("config.toml"))
}
let config = app_path!("config.toml", fn = get_xdg_config_path);
assert!(config.ends_with("config.toml"));
}
#[test]
fn test_fn_override_with_platform_specific_logic() {
fn get_platform_config_path() -> Option<PathBuf> {
if cfg!(windows) {
env::var("APPDATA")
.ok()
.map(|appdata| PathBuf::from(appdata).join("MyApp").join("config.toml"))
} else {
env::var("HOME").ok().map(|home| {
PathBuf::from(home)
.join(".config")
.join("myapp")
.join("config.toml")
})
}
}
let config = app_path!("config.toml", fn = get_platform_config_path);
assert!(config.ends_with("config.toml"));
}
#[test]
fn test_env_override_fallback_to_default() {
let config = app_path!("fallback.toml", env = "NONEXISTENT_ENV_VAR");
let expected = std::env::current_exe()
.unwrap()
.parent()
.unwrap()
.join("fallback.toml");
assert_eq!(&*config, &expected);
}
#[test]
fn test_multiple_override_scenarios() {
let temp_dir = env::temp_dir();
let env_path = temp_dir.join("env_config.toml");
env::set_var("MULTI_TEST_ENV", &env_path);
let config1 = app_path!("default.toml", env = "MULTI_TEST_ENV");
assert_eq!(&*config1, &env_path);
let direct_path = temp_dir.join("direct_config.toml");
let config2 = app_path!("default.toml", override = Some(direct_path.clone()));
assert_eq!(&*config2, &direct_path);
let fn_path = temp_dir.join("fn_config.toml");
let config3 = app_path!("default.toml", fn = || Some(fn_path.clone()));
assert_eq!(&*config3, &fn_path);
let config4 = app_path!("default.toml");
let expected = std::env::current_exe()
.unwrap()
.parent()
.unwrap()
.join("default.toml");
assert_eq!(&*config4, &expected);
env::remove_var("MULTI_TEST_ENV");
}
#[test]
fn test_try_app_path_env_override() {
let temp_dir = env::temp_dir();
let custom_path = temp_dir.join("try_env_override.toml");
env::set_var("TRY_TEST_ENV_OVERRIDE", &custom_path);
let config = try_app_path!("default.toml", env = "TRY_TEST_ENV_OVERRIDE").unwrap();
assert_eq!(&*config, &custom_path);
env::remove_var("TRY_TEST_ENV_OVERRIDE");
}
#[test]
fn test_try_app_path_direct_override() {
let override_path = if cfg!(windows) {
PathBuf::from("C:\\custom\\try\\override.toml")
} else {
PathBuf::from("/custom/try/override.toml")
};
let config = try_app_path!("default.toml", override = Some(override_path.clone())).unwrap();
assert_eq!(&*config, &override_path);
}
#[test]
fn test_try_app_path_fn_override() {
let custom_path = env::temp_dir().join("try_fn_override.toml");
let config = try_app_path!("default.toml", fn = || Some(custom_path.clone())).unwrap();
assert_eq!(&*config, &custom_path);
}
#[test]
fn test_try_app_path_override_equivalence() {
let temp_dir = env::temp_dir();
let test_path = temp_dir.join("equivalence_test.toml");
let panicking = app_path!("test.toml", override = Some(test_path.clone()));
let fallible = try_app_path!("test.toml", override = Some(test_path.clone())).unwrap();
assert_eq!(panicking, fallible);
env::set_var("EQUIV_TEST_ENV", &test_path);
let panicking_env = app_path!("test.toml", env = "EQUIV_TEST_ENV");
let fallible_env = try_app_path!("test.toml", env = "EQUIV_TEST_ENV").unwrap();
assert_eq!(panicking_env, fallible_env);
env::remove_var("EQUIV_TEST_ENV");
let panicking_fn = app_path!("test.toml", fn = || Some(test_path.clone()));
let fallible_fn = try_app_path!("test.toml", fn = || Some(test_path.clone())).unwrap();
assert_eq!(panicking_fn, fallible_fn);
}