use tiptap_rusty_parser::{LeafPolicy, Node, PosError, Position};
fn p(text: &str) -> Node {
Node::element("paragraph").with_child(Node::text(text))
}
fn sample() -> Node {
Node::element("doc").with_children([p("hi"), Node::element("horizontalRule"), p("ok")])
}
#[test]
fn node_sizes() {
let d = sample();
assert_eq!(d.content_size(), 9);
assert_eq!(d.child(0).unwrap().node_size(), 4); assert_eq!(d.child(1).unwrap().node_size(), 1); assert_eq!(d.child(0).unwrap().child(0).unwrap().node_size(), 2); }
#[test]
fn empty_paragraph_is_a_container_not_a_leaf() {
let empty_para = Node::element("paragraph").with_children(Vec::<Node>::new());
assert!(!empty_para.is_leaf());
assert_eq!(empty_para.node_size(), 2);
let bare = Node::element("paragraph");
assert!(!bare.is_leaf());
assert_eq!(bare.node_size(), 2);
assert!(Node::element("image").is_leaf());
assert_eq!(Node::element("image").node_size(), 1);
}
#[test]
fn leaf_policy_override() {
let custom = LeafPolicy::from_types(["mediaEmbed"]);
let n = Node::element("mediaEmbed");
assert!(n.is_leaf_with(&custom));
assert_eq!(n.node_size_with(&custom), 1);
assert_eq!(n.node_size(), 2);
}
#[test]
fn hand_computed_positions() {
let d = sample();
assert_eq!(d.pos_before(&[0]).unwrap(), 0); assert_eq!(d.pos_after(&[0]).unwrap(), 4);
assert_eq!(d.pos_before(&[1]).unwrap(), 4); assert_eq!(d.pos_after(&[1]).unwrap(), 5);
assert_eq!(d.pos_before(&[2]).unwrap(), 5); assert_eq!(d.pos_after(&[2]).unwrap(), 9);
assert_eq!(d.pos_before(&[0, 0]).unwrap(), 1);
assert_eq!(d.pos_in_text(&[0, 0], 0).unwrap(), 1);
assert_eq!(d.pos_in_text(&[0, 0], 1).unwrap(), 2);
assert_eq!(d.pos_in_text(&[0, 0], 2).unwrap(), 3);
}
#[test]
fn resolve_boundaries_and_text() {
let d = sample();
let r = d.resolve(0).unwrap();
assert_eq!(r.path, Vec::<usize>::new());
assert_eq!(r.index, 0);
assert!(!r.is_in_text());
let r = d.resolve(2).unwrap();
assert_eq!(r.path, vec![0]);
let tp = r.text_offset.unwrap();
assert_eq!(tp.path, vec![0, 0]);
assert_eq!(tp.offset, 1);
let r = d.resolve(4).unwrap();
assert_eq!(r.path, Vec::<usize>::new());
assert_eq!(r.index, 1);
assert!(!r.is_in_text());
let r = d.resolve(9).unwrap();
assert_eq!(r.path, Vec::<usize>::new());
assert_eq!(r.index, 3);
}
#[test]
fn invalid_construction_errors() {
let d = sample(); assert!(d.pos_before(&[3]).is_err());
assert!(d.pos_in_text(&[1], 0).is_err()); assert!(d.pos_in_text(&[0, 0], 2).is_ok()); assert!(d.pos_in_text(&[0, 0], 3).is_err()); assert!(d.inline_to_pos(&[0], Position::new(0, 99)).is_err()); assert!(d.inline_to_pos(&[0], Position::new(1, 1)).is_err()); assert!(d.inline_to_pos(&[0], Position::new(0, 2)).is_ok()); }
#[test]
fn resolve_out_of_range() {
let d = sample();
assert_eq!(
d.resolve(10),
Err(PosError::OutOfRange { pos: 10, size: 9 })
);
}
#[test]
fn resolve_roundtrips_pos_before() {
let d = sample();
for path in [vec![0], vec![1], vec![2]] {
let pos = d.pos_before(&path).unwrap();
let r = d.resolve(pos).unwrap();
assert_eq!(r.path, Vec::<usize>::new());
assert_eq!(r.index, *path.last().unwrap());
}
}
#[test]
fn resolve_every_position_is_ok() {
let d = sample();
for pos in 0..=d.content_size() {
let r = d.resolve(pos).unwrap();
assert_eq!(r.pos, pos);
}
}
#[test]
fn nested_blocks_positions() {
let d = Node::element("doc").with_child(
Node::element("bulletList").with_child(Node::element("listItem").with_child(p("xy"))),
);
assert_eq!(d.content_size(), 8);
assert_eq!(d.pos_before(&[0, 0, 0, 0]).unwrap(), 3); assert_eq!(d.pos_in_text(&[0, 0, 0, 0], 1).unwrap(), 4);
let r = d.resolve(4).unwrap(); assert_eq!(r.path, vec![0, 0, 0]);
assert_eq!(r.text_offset.unwrap().offset, 1);
}
#[test]
fn inline_bridges_roundtrip() {
let d = Node::element("doc")
.with_child(Node::element("paragraph").with_children([Node::text("ab"), Node::text("cd")]));
let (block, inline) = d.pos_to_inline(4).unwrap();
assert_eq!(block, vec![0]);
assert_eq!(inline, Position::new(1, 1));
assert_eq!(d.inline_to_pos(&[0], Position::new(1, 1)).unwrap(), 4);
let (b2, i2) = d.pos_to_inline(1).unwrap();
assert_eq!((b2, i2), (vec![0], Position::new(0, 0)));
assert_eq!(d.inline_to_pos(&[0], Position::new(0, 0)).unwrap(), 1);
}