use noyalib::cst::parse_document;
#[track_caller]
fn removes_exactly(src: &str, path: &str, want: &str) {
let mut doc = parse_document(src).expect("parse");
doc.remove(path).unwrap_or_else(|e| panic!("{path}: {e}"));
assert_eq!(doc.source(), want, "removing {path} from {src:?}");
assert!(
!doc.source().is_empty(),
"the original bug: removing {path} emptied the document"
);
let _reparsed = parse_document(doc.source()).expect("result re-parses");
}
#[test]
fn flow_mapping_entry_does_not_delete_the_document() {
removes_exactly("a: {x: 1, y: 2}\n", "a.x", "a: {y: 2}\n");
}
#[test]
fn flow_mapping_entry_does_not_delete_its_parent() {
removes_exactly("keep: 0\na: {x: 1, y: 2}\n", "a.x", "keep: 0\na: {y: 2}\n");
removes_exactly("a: {x: 1, y: 2}\nkeep: 9\n", "a.y", "a: {x: 1}\nkeep: 9\n");
}
#[test]
fn flow_sequence_item_is_removed_not_the_sequence() {
removes_exactly("a: [1, 2, 3]\n", "a[1]", "a: [1, 3]\n");
}
#[test]
fn sole_entry_becomes_an_empty_collection_rather_than_nothing() {
removes_exactly("only: 1\n", "only", "{}\n");
}
#[test]
fn the_cases_that_worked_still_work() {
for (src, path, want) in [
("a: 1\nb: 2\n", "a", "b: 2\n"),
("a: |\n one\n two\nb: 2\n", "a", "b: 2\n"),
("a:\n x: 1\n y: 2\nb: 2\n", "a", "b: 2\n"),
("a:\n - 1\n - 2\n", "a[0]", "a:\n - 2\n"),
] {
let mut doc = parse_document(src).expect("parse");
doc.remove(path).unwrap_or_else(|e| panic!("{path}: {e}"));
assert_eq!(doc.source(), want, "removing {path} from {src:?}");
}
}
#[test]
fn a_flow_remove_changes_the_value_by_exactly_one_key() {
let src = "a: {x: 1, y: 2}\nb: 3\n";
let mut doc = parse_document(src).expect("parse");
doc.remove("a.x").expect("remove");
let after: noyalib::Value = noyalib::from_str(doc.source()).expect("after");
let expected: noyalib::Value = noyalib::from_str("a: {y: 2}\nb: 3\n").expect("expected");
assert_eq!(after, expected);
}
#[test]
fn a_genuinely_refused_remove_still_leaves_the_value_intact() {
let src = "a: {x: 1, y: 2}\n";
let mut doc = parse_document(src).expect("parse");
let before: noyalib::Value = noyalib::from_str(src).expect("before");
assert!(doc.remove("a.nope").is_err());
assert_eq!(doc.source(), src, "source untouched after a refusal");
let after: noyalib::Value = noyalib::from_str(doc.source()).expect("after");
assert_eq!(before, after, "a refused remove must not change the value");
}