use guix_scheme::record::RecordViewMut;
use scheme_edit::{list, string_lit, sym, Document};
fn fixture() -> String {
std::fs::read_to_string(concat!(
env!("CARGO_MANIFEST_DIR"),
"/../scheme-edit/tests/fixtures/system/live-panther.scm"
))
.unwrap()
}
fn diff_lines(a: &str, b: &str) -> usize {
a.lines().zip(b.lines()).filter(|(x, y)| x != y).count()
}
#[test]
fn roundtrips_byte_identical() {
let src = fixture();
let doc = Document::parse(&src).unwrap();
assert_eq!(doc.to_string(), src);
}
#[test]
fn host_name_edit_is_single_line_diff() {
let src = fixture();
let mut doc = Document::parse(&src).unwrap();
let os = doc
.forms_mut()
.find(|n| n.head_symbol() == Some("operating-system"))
.unwrap();
let mut v = RecordViewMut::new(os).unwrap();
v.set_field("host-name", string_lit("renamed"));
let out = doc.to_string();
assert!(out.contains("(host-name \"renamed\")"));
assert_eq!(diff_lines(&src, &out), 1);
}
#[test]
fn service_swap_preserves_everything_else() {
let src = fixture();
let mut doc = Document::parse(&src).unwrap();
{
let os = doc
.forms_mut()
.find(|n| n.head_symbol() == Some("operating-system"))
.unwrap();
let mut v = RecordViewMut::new(os).unwrap();
let services = v.field_mut("services").unwrap();
assert_eq!(services.head_symbol(), Some("append"));
let list_idx = services
.position_of(|n| n.head_symbol() == Some("list"))
.unwrap();
let inner = services.data_child_mut(list_idx).unwrap();
let xfce = inner
.position_of(|n| n.to_source().contains("xfce-desktop-service-type"))
.unwrap();
inner.replace_child(
xfce,
list(vec![sym("service"), sym("plasma-desktop-service-type")]),
);
}
let out = doc.to_string();
assert!(out.contains("(service plasma-desktop-service-type)"));
assert!(!out.contains("xfce"));
assert!(out.contains("(service openssh-service-type)"));
assert!(out.contains("%os-desktop-services"));
assert_eq!(diff_lines(&src, &out), 1);
}
#[test]
fn user_comment_edit_is_single_line_diff() {
let src = fixture();
let mut doc = Document::parse(&src).unwrap();
{
let os = doc
.forms_mut()
.find(|n| n.head_symbol() == Some("operating-system"))
.unwrap();
let mut v = RecordViewMut::new(os).unwrap();
let users = v.field_mut("users").unwrap();
assert_eq!(users.head_symbol(), Some("cons"));
let ua_idx = users
.position_of(|n| n.head_symbol() == Some("user-account"))
.unwrap();
let ua = users.data_child_mut(ua_idx).unwrap();
let mut uv = RecordViewMut::new(ua).unwrap();
uv.set_field("comment", string_lit("Panther User"));
}
let out = doc.to_string();
assert!(out.contains("(comment \"Panther User\")"));
assert!(out.contains("(supplementary-groups '(\"wheel\" \"audio\" \"video\"))"));
assert_eq!(diff_lines(&src, &out), 1);
}