#![forbid(unsafe_code)]
mod arena;
mod tiers;
mod tree;
pub use arena::{Arena, ArenaBuilder, ArenaNode};
pub use tiers::{
Caps, Color, ComputedStyle, Interaction, NameSource, Rect, Rendering, Semantics, Tier,
};
pub use tree::{
Document, Node, NodeId, NodeKind, ancestors, closest, descendants, elements, has_text,
self_and_descendants, subtree_text,
};
#[cfg(test)]
mod tests {
use super::*;
fn doc() -> Arena {
Arena::builder()
.open("html")
.attr("lang", "de")
.open("head")
.open("title")
.text("Seite")
.close()
.close()
.open("body")
.open("main")
.open("h1")
.text("Titel")
.close()
.open("p")
.text("Ein ")
.open("a")
.attr("href", "/x")
.text("Link")
.close()
.text(".")
.close()
.close()
.close()
.close()
.build()
}
#[test]
fn wurzel_und_attribute() {
let d = doc();
assert_eq!(d.root().local_name(), "html");
assert_eq!(d.root().attr("lang"), Some("de"));
assert!(d.root().has_attr("lang"));
assert!(!d.root().has_attr("dir"));
}
#[test]
fn nachfahren_kommen_in_dokumentreihenfolge() {
let d = doc();
let namen: Vec<&str> = elements(&d).map(|n| n.local_name()).collect();
assert_eq!(
namen,
vec!["html", "head", "title", "body", "main", "h1", "p", "a"]
);
}
#[test]
fn subtree_text_sammelt_ueber_verschachtelung() {
let d = doc();
let p = elements(&d).find(|n| n.local_name() == "p").unwrap();
assert_eq!(subtree_text(p), "Ein Link.");
assert!(has_text(p));
}
#[test]
fn eigener_text_ist_nicht_teilbaumtext() {
let d = doc();
let p = elements(&d).find(|n| n.local_name() == "p").unwrap();
assert_eq!(p.text(), "");
assert_eq!(subtree_text(p), "Ein Link.");
}
#[test]
fn vorfahren_und_closest() {
let d = doc();
let a = elements(&d).find(|n| n.local_name() == "a").unwrap();
let kette: Vec<&str> = ancestors(a).map(|n| n.local_name()).collect();
assert_eq!(kette, vec!["p", "main", "body", "html"]);
assert_eq!(closest(a, "main").map(|n| n.local_name()), Some("main"));
assert_eq!(closest(a, "a").map(|n| n.local_name()), Some("a"));
assert!(closest(a, "form").is_none());
}
#[test]
fn knoten_lassen_sich_ueber_die_kennung_zurueckholen() {
let d = doc();
let h1 = elements(&d).find(|n| n.local_name() == "h1").unwrap();
let wieder = d.get(h1.id()).unwrap();
assert_eq!(wieder, h1);
assert!(d.get(NodeId(9999)).is_none());
}
#[test]
fn caps_kennt_struktur_immer() {
let nur_struktur = Caps::STRUCTURE_ONLY;
assert!(nur_struktur.has(Tier::Structure));
assert!(!nur_struktur.has(Tier::Semantics));
let voll = Caps::default()
.with_semantics()
.with_rendering()
.with_interaction();
assert!(voll.has(Tier::Rendering));
assert!(voll.has(Tier::Interaction));
}
#[test]
fn node_count_ist_optional_aber_hier_bekannt() {
let d = doc();
assert_eq!(d.node_count(), Some(d.len()));
}
}