use guix_scheme::ModuleFile;
use std::path::Path;
fn fx(dir: &str, name: &str) -> String {
let p = Path::new(env!("CARGO_MANIFEST_DIR"))
.join("../scheme-edit/tests/fixtures")
.join(dir)
.join(name);
std::fs::read_to_string(p).unwrap()
}
fn diff_lines(a: &str, b: &str) -> usize {
a.lines().zip(b.lines()).filter(|(x, y)| x != y).count()
}
fn assert_roundtrip_stable(out: &str) {
assert_eq!(ModuleFile::parse(out).unwrap().to_string(), out);
}
#[test]
fn cpio_reads() {
let src = fx("packages", "cpio.scm");
let mf = ModuleFile::parse(&src).unwrap();
assert_eq!(mf.to_string(), src);
assert!(mf.package_names().contains(&"cpio".to_string()));
let p = mf.package("cpio").unwrap();
assert_eq!(p.name().as_deref(), Some("cpio"));
assert_eq!(p.version().as_deref(), Some("2.15"));
assert_eq!(
p.synopsis().as_deref(),
Some("Manage cpio and tar file archives")
);
assert_eq!(
p.home_page().as_deref(),
Some("https://www.gnu.org/software/cpio/")
);
assert_eq!(
p.origin_sha256_base32().as_deref(),
Some("1nvmj2mc3nagpig75sgzvkqgzg1p01wgnlw54v4ix6ijgjwi0xlk")
);
assert!(p.inputs().is_empty());
assert!(p.native_inputs().is_empty());
assert!(p.propagated_inputs().is_empty());
}
#[test]
fn cpio_set_version_is_single_line_diff() {
let src = fx("packages", "cpio.scm");
let mut mf = ModuleFile::parse(&src).unwrap();
mf.package_mut("cpio").unwrap().set_version("2.16");
let out = mf.to_string();
assert!(out.contains("(version \"2.16\")"));
assert_eq!(diff_lines(&src, &out), 1);
assert_roundtrip_stable(&out);
let re = ModuleFile::parse(&out).unwrap();
assert_eq!(
re.package("cpio").unwrap().version().as_deref(),
Some("2.16")
);
}
#[test]
fn cpio_set_hash_is_single_line_diff() {
let src = fx("packages", "cpio.scm");
let new_hash = "0000000000000000000000000000000000000000000000000000";
let mut mf = ModuleFile::parse(&src).unwrap();
assert!(mf
.package_mut("cpio")
.unwrap()
.set_origin_sha256_base32(new_hash));
let out = mf.to_string();
assert_eq!(diff_lines(&src, &out), 1);
assert_roundtrip_stable(&out);
let re = ModuleFile::parse(&out).unwrap();
assert_eq!(
re.package("cpio")
.unwrap()
.origin_sha256_base32()
.as_deref(),
Some(new_hash)
);
}
#[test]
fn abiword_inputs_read() {
let src = fx("packages", "abiword.scm");
let mf = ModuleFile::parse(&src).unwrap();
let p = mf.package("abiword").unwrap();
assert_eq!(p.version().as_deref(), Some("3.0.7"));
let inputs = p.inputs();
assert_eq!(inputs.len(), 22);
for known in ["aspell", "boost", "gtk+", "readline", "zlib"] {
assert!(inputs.contains(&known.to_string()), "{known}");
}
let native = p.native_inputs();
assert_eq!(native.len(), 14);
assert!(native.contains(&"pkg-config".to_string()));
assert!(p.propagated_inputs().is_empty());
}
#[test]
fn abiword_replace_input_is_single_line_diff() {
let src = fx("packages", "abiword.scm");
let mut mf = ModuleFile::parse(&src).unwrap();
assert!(mf
.package_mut("abiword")
.unwrap()
.replace_input("readline", "libedit"));
let out = mf.to_string();
assert_eq!(diff_lines(&src, &out), 1);
assert_roundtrip_stable(&out);
let re = ModuleFile::parse(&out).unwrap();
let inputs = re.package("abiword").unwrap().inputs();
assert!(!inputs.contains(&"readline".to_string()));
assert!(inputs.contains(&"libedit".to_string()));
let changed: Vec<(&str, &str)> = src
.lines()
.zip(out.lines())
.filter(|(a, b)| a != b)
.collect();
assert_eq!(changed.len(), 1);
assert!(changed[0].0.contains("readline"));
assert!(changed[0].1.contains("libedit"));
}
#[test]
fn diagram_let_wrapped_packages() {
let src = fx("packages", "diagram.scm");
let mf = ModuleFile::parse(&src).unwrap();
let names = mf.package_names();
assert_eq!(names, vec!["pikchr".to_string(), "dpic".to_string()]);
for name in &names {
let p = mf.package(name).unwrap();
assert!(p.name().is_some_and(|n| !n.is_empty()));
assert_eq!(p.version(), None);
}
assert_eq!(
mf.package("dpic").unwrap().home_page().as_deref(),
Some("https://gitlab.com/aplevich/dpic")
);
assert_eq!(
mf.package("pikchr").unwrap().synopsis().as_deref(),
Some("Markup language for diagrams in technical documentation")
);
}
#[test]
fn service_modules_record_types() {
let avahi = ModuleFile::parse(&fx("services", "avahi.scm")).unwrap();
assert_eq!(
avahi.record_type_names(),
vec!["<avahi-configuration>".to_string()]
);
assert!(avahi.package_names().is_empty());
let auditd = ModuleFile::parse(&fx("services", "auditd.scm")).unwrap();
assert_eq!(
auditd.record_type_names(),
vec!["<auditd-configuration>".to_string()]
);
}
#[test]
fn hurd_module_parses_and_roundtrips() {
let src = fx("services", "hurd.scm");
let mf = ModuleFile::parse(&src).unwrap();
assert_eq!(mf.to_string(), src);
assert_eq!(
mf.record_type_names(),
vec![
"<hurd-console-configuration>".to_string(),
"<hurd-getty-configuration>".to_string(),
]
);
}