#![allow(unused_imports)]
use std::collections::HashMap;
use crate::gates::{GateTable, HostFacts};
use crate::handlers::HandlerConfig;
use crate::packs::Pack;
use crate::rules::{Rule, Scanner};
use crate::testing::TempEnvironment;
use super::{default_rules, host_pair, make_pack};
#[test]
fn dir_gate_passing_descends_and_flattens() {
let env = TempEnvironment::builder()
.pack("cross")
.file("_darwin/macos.sh", "#!/bin/sh\necho mac")
.file("shared", "x")
.done()
.build();
let scanner = Scanner::new(env.fs.as_ref());
let pack = make_pack("cross", env.dotfiles_root.join("cross"));
let (gates, host) = host_pair("darwin", "aarch64");
let matches = scanner
.scan_pack(&pack, &default_rules(), &[], &gates, &host, &HashMap::new())
.unwrap();
let names: Vec<String> = matches
.iter()
.map(|m| m.relative_path.to_string_lossy().to_string())
.collect();
assert!(names.contains(&"macos.sh".to_string()), "{names:?}");
assert!(names.contains(&"shared".to_string()), "{names:?}");
assert!(!names.iter().any(|n| n.starts_with("_darwin")), "{names:?}");
}
#[test]
fn dir_gate_failing_emits_gate_match() {
let env = TempEnvironment::builder()
.pack("cross")
.file("_linux/linux.sh", "#!/bin/sh\necho linux")
.file("shared", "x")
.done()
.build();
let scanner = Scanner::new(env.fs.as_ref());
let pack = make_pack("cross", env.dotfiles_root.join("cross"));
let (gates, host) = host_pair("darwin", "aarch64");
let matches = scanner
.scan_pack(&pack, &default_rules(), &[], &gates, &host, &HashMap::new())
.unwrap();
assert_eq!(matches.len(), 2, "{matches:?}");
let gate_match = matches
.iter()
.find(|m| m.handler == crate::handlers::HANDLER_GATE)
.expect("expected gate match");
assert_eq!(gate_match.relative_path.to_string_lossy(), "_linux");
assert!(gate_match.is_dir);
assert_eq!(
gate_match.options.get("gate_label"),
Some(&"linux".to_string())
);
let shared = matches
.iter()
.find(|m| m.relative_path.to_string_lossy() == "shared")
.expect("expected shared file");
assert_eq!(shared.handler, "symlink");
}
#[test]
fn dir_gate_routing_prefix_is_not_a_gate() {
let env = TempEnvironment::builder()
.pack("p")
.file("_home/.bashrc", "# bashrc")
.done()
.build();
let scanner = Scanner::new(env.fs.as_ref());
let pack = make_pack("p", env.dotfiles_root.join("p"));
let (gates, host) = host_pair("darwin", "aarch64");
let matches = scanner
.scan_pack(&pack, &default_rules(), &[], &gates, &host, &HashMap::new())
.unwrap();
assert_eq!(matches.len(), 1);
let m = &matches[0];
assert_eq!(m.relative_path.to_string_lossy(), "_home");
assert!(m.is_dir);
assert_eq!(m.handler, "symlink");
}
#[test]
fn dir_gate_unknown_label_is_hard_error() {
let env = TempEnvironment::builder()
.pack("typo")
.file("_darwn/foo.sh", "x") .done()
.build();
let scanner = Scanner::new(env.fs.as_ref());
let pack = make_pack("typo", env.dotfiles_root.join("typo"));
let (gates, host) = host_pair("darwin", "aarch64");
let err = scanner
.scan_pack(&pack, &default_rules(), &[], &gates, &host, &HashMap::new())
.unwrap_err();
let msg = err.to_string();
assert!(msg.contains("darwn"), "missing label: {msg}");
assert!(msg.contains("_darwn"), "missing dir name: {msg}");
}
#[test]
fn dir_gate_nested_inside_passing_gate_still_evaluates() {
let env = TempEnvironment::builder()
.pack("p")
.file("_darwin/_arm64/install.sh", "x")
.done()
.build();
let scanner = Scanner::new(env.fs.as_ref());
let pack = make_pack("p", env.dotfiles_root.join("p"));
let (gates, host) = host_pair("darwin", "aarch64");
let matches = scanner
.scan_pack(&pack, &default_rules(), &[], &gates, &host, &HashMap::new())
.unwrap();
assert_eq!(matches.len(), 1);
let m = &matches[0];
assert_eq!(m.relative_path.to_string_lossy(), "install.sh");
assert_eq!(m.handler, "install");
}
#[test]
fn dir_gate_nested_failing_inner_gate_drops_subtree() {
let env = TempEnvironment::builder()
.pack("p")
.file("_darwin/_x86_64/install.sh", "x")
.done()
.build();
let scanner = Scanner::new(env.fs.as_ref());
let pack = make_pack("p", env.dotfiles_root.join("p"));
let (gates, host) = host_pair("darwin", "aarch64");
let matches = scanner
.scan_pack(&pack, &default_rules(), &[], &gates, &host, &HashMap::new())
.unwrap();
let gate = matches
.iter()
.find(|m| m.handler == crate::handlers::HANDLER_GATE);
assert!(gate.is_some(), "expected a gate match: {matches:?}");
assert!(
!matches
.iter()
.any(|m| m.relative_path.to_string_lossy() == "install.sh"),
"install.sh must not deploy when its enclosing gate fails: {matches:?}"
);
}
#[test]
fn dir_gate_with_routing_prefix_inside_passing_gate() {
let env = TempEnvironment::builder()
.pack("p")
.file("_darwin/_home/.bashrc", "# bashrc")
.done()
.build();
let scanner = Scanner::new(env.fs.as_ref());
let pack = make_pack("p", env.dotfiles_root.join("p"));
let (gates, host) = host_pair("darwin", "aarch64");
let matches = scanner
.scan_pack(&pack, &default_rules(), &[], &gates, &host, &HashMap::new())
.unwrap();
assert_eq!(matches.len(), 1);
let m = &matches[0];
assert_eq!(m.relative_path.to_string_lossy(), "_home");
assert!(m.is_dir);
assert_eq!(m.handler, "symlink");
}