#![allow(
clippy::unwrap_used,
clippy::expect_used,
clippy::indexing_slicing,
clippy::panic
)]
use std::fmt::Write as _;
use oneyaml::{CommentOwner, Document, Value, path};
fn value_at(d: &Document, p: &oneyaml::Path) -> Value {
d.get_path(p).unwrap().deserialize::<Value>().unwrap()
}
#[test]
fn re_setting_the_tail_reader_keeps_its_style() {
let cases: [(&str, oneyaml::Path); 11] = [
("k: |+\n x\n ", path!["k"]),
("k: |+\n x\n\n ", path!["k"]),
("a: 1\nk: |+\n x\n\n ", path!["k"]),
("- |+\n x\n\n ", path![0]),
("k: |2+\n x\n ", path!["k"]),
("k: &a |+\n x\n ", path!["k"]),
("k: !t |+\n x\n ", path!["k"]),
("k: &a !t |+ # c\n x\n ", path!["k"]),
("k: |+ # c\n x\n\n # d\n ", path!["k"]),
("k: |+\n\n ", path!["k"]),
("k: >+\n x\n ", path!["k"]),
];
for (src, p) in cases {
let mut d = Document::parse(src).unwrap();
let v = value_at(&d, &p);
let old = d.id_of(&p).unwrap();
let new = d.node_mut(old).unwrap().set(&v).unwrap().id();
assert_eq!(d.to_string().as_bytes(), src.as_bytes(), "{src:?}");
assert_eq!(new, old, "{src:?}");
assert!(d.node(old).is_ok(), "{src:?}");
assert_eq!(value_at(&d, &p), v, "{src:?}");
let again = Document::parse(d.to_string()).unwrap();
assert_eq!(value_at(&again, &p), v, "{src:?}");
let mut d = Document::parse(src).unwrap();
d.set_path(&p, &v).unwrap();
assert_eq!(d.to_string().as_bytes(), src.as_bytes(), "{src:?}");
}
}
#[test]
fn other_values_are_written_as_before() {
let mut d = Document::parse("k: |+\n x\n ").unwrap();
d.set_path(&path!["k"], "y\n\n").unwrap();
assert_eq!(d.to_string(), "k: \"y\\n\\n\"\n ");
assert_eq!(value_at(&d, &path!["k"]), Value::from("y\n\n"));
let mut d = Document::parse("k: |+\n x\n").unwrap();
d.set_path(&path!["k"], "x\n").unwrap();
assert_eq!(d.to_string(), "k: |+\n x\n");
d.set_path(&path!["k"], "y\n").unwrap();
assert_eq!(d.to_string(), "k: |\n y\n");
let mut d = Document::parse("k: |+\n x\n\nz: 1\n ").unwrap();
let v = value_at(&d, &path!["k"]);
d.set_path(&path!["k"], &v).unwrap();
assert_eq!(value_at(&d, &path!["k"]), v);
let mut d = Document::parse("k: !t |+\n x\n ").unwrap();
d.set_path(&path!["k"], "x\n\n").unwrap();
assert_eq!(value_at(&d, &path!["k"]), Value::from("x\n\n"));
assert!(!d.to_string().contains("!t"));
}
fn big(n: usize) -> String {
let mut s = String::from("# head\n\na: 0\nbig:\n");
for i in 0..n {
match i % 5 {
0 => writeln!(s, " # lead {i}\n k{i}: v{i} # t{i}").unwrap(),
1 => writeln!(s, " k{i}: &x{i} {{p: [q, {i}]}}").unwrap(),
2 => writeln!(s, " k{i}:\n - {i}\n # foot {i}").unwrap(),
3 => writeln!(s, " k{i}: |\n line {i}\n").unwrap(),
_ => writeln!(s, " k{i}: value {i}").unwrap(),
}
}
s.push_str(" # big footer\nonly:\n inner:\n");
for i in 0..n {
writeln!(s, " o{i}: {i} # o{i}").unwrap();
}
s.push_str("z: 1\n");
s
}
#[test]
fn big_entries_carry_their_comments() {
let src = big(400);
let comments = |d: &Document| d.explain_comments().unwrap().len();
let mut d = Document::parse(src.as_str()).unwrap();
let all = comments(&d);
let r = d.remove_node(d.id_of(&path!["big"]).unwrap()).unwrap();
assert_eq!(r.comments().len(), 80 * 3 + 1);
assert_eq!(comments(&d) + r.comments().len(), all);
d.root_mut().unwrap().insert_removed_at(1, r).unwrap();
assert_eq!(d.to_string(), src);
let mut d = Document::parse(src.as_str()).unwrap();
d.set_path(&path!["big"], 1).unwrap();
assert!(
d.to_string()
.starts_with("# head\n\na: 0\nbig:\n 1\nonly:\n")
);
assert_eq!(comments(&d), 1 + 400);
let mut d = Document::parse(src.as_str()).unwrap();
let r = d
.remove_node(d.id_of(&path!["only", "inner"]).unwrap())
.unwrap();
assert_eq!(r.comments().len(), 400);
assert!(d.to_string().contains("only: {}\nz: 1\n"));
let mut d = Document::parse(src.as_str()).unwrap();
let head = d.comment_ids()[0];
let k5 = d.id_of(&path!["big", "k5"]).unwrap();
d.attach_comment(head, CommentOwner::Trailing(k5)).unwrap();
let r = d.remove_node(d.id_of(&path!["big"]).unwrap()).unwrap();
d.root_mut().unwrap().insert_removed_at(1, r).unwrap();
assert_eq!(d.to_string(), src);
let k5 = d.id_of(&path!["big", "k5"]).unwrap();
let owned = d.comments(k5).unwrap();
assert!(
owned.trailing().iter().any(|c| c.is_explicit()),
"{owned:?}"
);
}