use gwm::bootstrap::evaluate_when;
use tempfile::TempDir;
const UNSET_VAR: &str = "GWM_TEST_PREDICATE_DEFINITELY_UNSET_8c4f9a";
#[test]
fn file_exists_true_when_target_present() {
let dir = TempDir::new().unwrap();
std::fs::write(dir.path().join("Cargo.toml"), "[package]").unwrap();
assert!(evaluate_when("file_exists:Cargo.toml", dir.path()));
}
#[test]
fn file_exists_false_when_target_missing() {
let dir = TempDir::new().unwrap();
assert!(!evaluate_when("file_exists:Cargo.toml", dir.path()));
}
#[test]
fn cmd_exists_true_for_sh() {
let dir = TempDir::new().unwrap();
assert!(evaluate_when("cmd_exists:sh", dir.path()));
}
#[test]
fn cmd_exists_false_for_made_up_binary() {
let dir = TempDir::new().unwrap();
assert!(!evaluate_when(
"cmd_exists:gwm_test_definitely_no_such_binary_4f7a3b",
dir.path()
));
}
#[test]
fn env_set_true_for_path() {
let dir = TempDir::new().unwrap();
assert!(evaluate_when("env_set:PATH", dir.path()));
}
#[test]
fn env_set_false_for_unset_var() {
let dir = TempDir::new().unwrap();
let expr = format!("env_set:{}", UNSET_VAR);
assert!(!evaluate_when(&expr, dir.path()));
}
#[test]
fn env_eq_true_when_value_matches() {
let dir = TempDir::new().unwrap();
let (name, value) = std::env::vars()
.find(|(_, v)| !v.is_empty() && !v.contains(char::is_whitespace) && !v.contains("&&") && !v.contains("||"))
.expect("at least one env var should have a simple value at test time");
let expr = format!("env_eq:{}={}", name, value);
assert!(
evaluate_when(&expr, dir.path()),
"expected env_eq:{}={} to evaluate true",
name,
value
);
}
#[test]
fn env_eq_false_when_value_mismatch() {
let dir = TempDir::new().unwrap();
assert!(!evaluate_when(
"env_eq:PATH=/definitely/not/the/real/path/xyz",
dir.path()
));
}
#[test]
fn env_eq_false_when_var_missing() {
let dir = TempDir::new().unwrap();
let expr = format!("env_eq:{}=whatever", UNSET_VAR);
assert!(!evaluate_when(&expr, dir.path()));
}
#[test]
fn glob_exists_true_when_pattern_matches_in_root() {
let dir = TempDir::new().unwrap();
std::fs::write(dir.path().join("main.rs"), "fn main() {}").unwrap();
assert!(evaluate_when("glob_exists:*.rs", dir.path()));
}
#[test]
fn glob_exists_true_for_recursive_pattern() {
let dir = TempDir::new().unwrap();
std::fs::create_dir_all(dir.path().join("src/inner")).unwrap();
std::fs::write(dir.path().join("src/inner/lib.rs"), "// nested").unwrap();
assert!(evaluate_when("glob_exists:**/*.rs", dir.path()));
}
#[test]
fn glob_exists_false_when_no_match() {
let dir = TempDir::new().unwrap();
std::fs::write(dir.path().join("README.md"), "no rust").unwrap();
assert!(!evaluate_when("glob_exists:*.rs", dir.path()));
}
#[test]
fn not_inverts_file_exists_true() {
let dir = TempDir::new().unwrap();
std::fs::write(dir.path().join("a"), "").unwrap();
assert!(!evaluate_when("!file_exists:a", dir.path()));
}
#[test]
fn not_inverts_file_exists_false() {
let dir = TempDir::new().unwrap();
assert!(evaluate_when("!file_exists:missing", dir.path()));
}
#[test]
fn and_true_when_both_sides_true() {
let dir = TempDir::new().unwrap();
std::fs::write(dir.path().join("a"), "").unwrap();
std::fs::write(dir.path().join("b"), "").unwrap();
assert!(evaluate_when("file_exists:a && file_exists:b", dir.path()));
}
#[test]
fn and_false_when_left_false() {
let dir = TempDir::new().unwrap();
std::fs::write(dir.path().join("b"), "").unwrap();
assert!(!evaluate_when("file_exists:a && file_exists:b", dir.path()));
}
#[test]
fn and_false_when_right_false() {
let dir = TempDir::new().unwrap();
std::fs::write(dir.path().join("a"), "").unwrap();
assert!(!evaluate_when("file_exists:a && file_exists:b", dir.path()));
}
#[test]
fn or_true_when_left_true() {
let dir = TempDir::new().unwrap();
std::fs::write(dir.path().join("a"), "").unwrap();
assert!(evaluate_when("file_exists:a || file_exists:b", dir.path()));
}
#[test]
fn or_true_when_right_true() {
let dir = TempDir::new().unwrap();
std::fs::write(dir.path().join("b"), "").unwrap();
assert!(evaluate_when("file_exists:a || file_exists:b", dir.path()));
}
#[test]
fn or_false_when_both_sides_false() {
let dir = TempDir::new().unwrap();
assert!(!evaluate_when("file_exists:a || file_exists:b", dir.path()));
}
#[test]
fn precedence_not_binds_tighter_than_and() {
let dir = TempDir::new().unwrap();
std::fs::write(dir.path().join("b"), "").unwrap();
assert!(evaluate_when("!file_exists:a && file_exists:b", dir.path()));
}
#[test]
fn precedence_and_binds_tighter_than_or() {
let dir = TempDir::new().unwrap();
std::fs::write(dir.path().join("a"), "").unwrap();
assert!(evaluate_when(
"file_exists:a || file_exists:b && file_exists:c",
dir.path()
));
}
#[test]
fn precedence_and_binds_tighter_than_or_negative() {
let dir = TempDir::new().unwrap();
std::fs::write(dir.path().join("b"), "").unwrap();
assert!(!evaluate_when(
"file_exists:a || file_exists:b && file_exists:c",
dir.path()
));
}
#[test]
fn extra_whitespace_around_operators_is_tolerated() {
let dir = TempDir::new().unwrap();
std::fs::write(dir.path().join("a"), "").unwrap();
std::fs::write(dir.path().join("b"), "").unwrap();
assert!(evaluate_when(" file_exists:a && file_exists:b ", dir.path()));
}
#[test]
fn unicode_whitespace_inside_atom_is_trimmed() {
let dir = TempDir::new().unwrap();
std::fs::write(dir.path().join("payload"), "").unwrap();
let expr = "file_exists:\u{00A0}payload";
assert!(
evaluate_when(expr, dir.path()),
"expected `file_exists:` to strip leading Unicode whitespace"
);
}
#[test]
fn unicode_path_does_not_panic() {
let dir = TempDir::new().unwrap();
std::fs::write(dir.path().join("σ.rs"), "// greek lowercase sigma").unwrap();
assert!(evaluate_when("file_exists:σ.rs", dir.path()));
assert!(!evaluate_when("file_exists:λ.rs", dir.path()));
}
#[test]
fn unknown_keyword_still_defaults_to_true() {
let dir = TempDir::new().unwrap();
assert!(evaluate_when("totally_made_up:whatever", dir.path()));
}