use hocon::{ParseOptions, ResolveOptions};
#[test]
fn resolve_on_already_resolved_is_idempotent() {
let c = hocon::parse(r#"a = 1"#).unwrap();
assert!(c.is_resolved());
let r = c.resolve(ResolveOptions::defaults()).unwrap();
assert!(r.is_resolved());
assert_eq!(r.get_i64("a").unwrap(), 1);
let r2 = r.resolve(ResolveOptions::defaults()).unwrap();
assert_eq!(r2.get_i64("a").unwrap(), 1);
}
#[test]
fn resolve_deferred_path_succeeds() {
let c = hocon::parse_string_with_options(
r#"a = ${b}
b = 1"#,
ParseOptions::defaults().with_resolve_substitutions(false),
)
.unwrap();
assert!(!c.is_resolved());
let r = c.resolve(ResolveOptions::defaults()).unwrap();
assert!(r.is_resolved());
assert_eq!(r.get_i64("a").unwrap(), 1);
}
#[test]
fn resolve_allow_unresolved_does_not_error() {
let c = hocon::parse_string_with_options(
r#"a = ${avail}
b = ${unavail}
avail = "hello""#,
ParseOptions::defaults().with_resolve_substitutions(false),
)
.unwrap();
let r = c
.resolve(
ResolveOptions::defaults()
.with_allow_unresolved(true)
.with_use_system_environment(false),
)
.unwrap();
assert!(!r.is_resolved());
assert_eq!(r.get_string("a").unwrap(), "hello");
assert!(r.get_string("b").is_err());
}
#[test]
fn resolve_no_system_environment_errors_on_missing() {
std::env::set_var("RS_HOCON_TEST_RESOLVE_ENV", "from-env");
let c = hocon::parse_string_with_options(
r#"a = ${RS_HOCON_TEST_RESOLVE_ENV}"#,
ParseOptions::defaults().with_resolve_substitutions(false),
)
.unwrap();
let result = c.resolve(ResolveOptions::defaults().with_use_system_environment(false));
std::env::remove_var("RS_HOCON_TEST_RESOLVE_ENV");
assert!(result.is_err());
}
#[test]
fn resolve_allow_unresolved_then_fallback_rereresolves() {
let c = hocon::parse_string_with_options(
"a = ${b}\nx = 1",
ParseOptions::defaults().with_resolve_substitutions(false),
)
.unwrap();
assert!(!c.is_resolved());
let partial = c
.resolve(
ResolveOptions::defaults()
.with_allow_unresolved(true)
.with_use_system_environment(false),
)
.unwrap();
assert!(!partial.is_resolved(), "a should still be unresolved");
assert_eq!(partial.get_i64("x").unwrap(), 1);
let fallback = hocon::parse("b = 2").unwrap();
assert!(fallback.is_resolved());
let full = partial
.with_fallback(&fallback)
.resolve(
ResolveOptions::defaults()
.with_allow_unresolved(false)
.with_use_system_environment(false),
)
.unwrap();
assert!(full.is_resolved());
assert_eq!(full.get_i64("a").unwrap(), 2, "a should now resolve to b=2");
assert_eq!(full.get_i64("x").unwrap(), 1);
}
#[test]
fn resolve_allow_unresolved_concat_then_fallback_rereresolves() {
let c = hocon::parse_string_with_options(
"a = ${x} ${y}\nx = \"hello\"",
ParseOptions::defaults().with_resolve_substitutions(false),
)
.unwrap();
assert!(!c.is_resolved());
let partial = c
.resolve(
ResolveOptions::defaults()
.with_allow_unresolved(true)
.with_use_system_environment(false),
)
.unwrap();
assert!(
!partial.is_resolved(),
"concat a should still be unresolved"
);
let fallback = hocon::parse("y = \"world\"").unwrap();
let full = partial
.with_fallback(&fallback)
.resolve(
ResolveOptions::defaults()
.with_allow_unresolved(false)
.with_use_system_environment(false),
)
.unwrap();
assert!(full.is_resolved());
assert_eq!(
full.get_string("a").unwrap(),
"hello world",
"concat should resolve to 'hello world' after fallback provides y"
);
}