elements under the document and
// returns (outermost_div, innermost_div). Depth this large overflows a
// recursive tree walk and aborts the process, so it guards the iterative
// serialize / text_content / import paths against regressing to recursion.
fn build_deep_chain(tree: &DomTree, depth: usize) -> (NodeId, NodeId) {
let mk_div = || {
tree.new_node(NodeData::Element {
name: QualName::new(None, ns!(html), local_name!("div")),
attrs: vec![],
template_contents: None,
mathml_annotation_xml_integration_point: false,
})
};
let root = mk_div();
tree.append_child(tree.document(), root);
let mut cur = root;
for _ in 1..depth {
let next = mk_div();
tree.append_child(cur, next);
cur = next;
}
(root, cur)
}
#[test]
fn test_outer_html_deeply_nested_does_not_overflow() {
let tree = DomTree::new();
let (root, leaf) = build_deep_chain(&tree, 100_000);
let marker = tree.new_node(NodeData::Text {
contents: "leaf".into(),
});
tree.append_child(leaf, marker);
let html = tree.outer_html(root);
assert!(html.starts_with("
"));
assert!(html.contains("leaf"));
assert!(html.ends_with("
"));
}
#[test]
fn test_text_content_deeply_nested_does_not_overflow() {
let tree = DomTree::new();
let (root, leaf) = build_deep_chain(&tree, 100_000);
let marker = tree.new_node(NodeData::Text {
contents: "deep".into(),
});
tree.append_child(leaf, marker);
assert_eq!(tree.text_content(root), "deep");
}
#[test]
fn test_import_deeply_nested_does_not_overflow() {
let source = DomTree::new();
build_deep_chain(&source, 100_000);
let dest = DomTree::new();
let dest_doc = dest.document();
dest.import_children_from(dest_doc, &source, source.document());
assert!(dest.len() >= 100_000);
}
}