use skyscraper::{
html,
xpath::{self, grammar::data_model::XpathItem},
};
#[test]
fn self_axis_returns_context_node() {
let text = r#"<html><body><p>hello</p></body></html>"#;
let document = html::parse(text).unwrap();
let xpath = xpath::parse("//p/self::node()").unwrap();
let items = xpath.apply(&document).unwrap();
assert_eq!(items.len(), 1);
let node = items[0].extract_as_node();
assert_eq!(node.extract_as_element_node().name, "p");
}
#[test]
fn self_axis_with_name_test() {
let text = r#"<html><body><p>one</p><div>two</div></body></html>"#;
let document = html::parse(text).unwrap();
let xpath = xpath::parse("//body/*/self::p").unwrap();
let items = xpath.apply(&document).unwrap();
assert_eq!(items.len(), 1);
let node = items[0].extract_as_node();
assert_eq!(node.extract_as_element_node().name, "p");
}
#[test]
fn self_axis_dot_abbreviation() {
let text = r#"<html><body><p>text</p></body></html>"#;
let document = html::parse(text).unwrap();
let xpath = xpath::parse("//p/.").unwrap();
let items = xpath.apply(&document).unwrap();
assert_eq!(items.len(), 1);
let node = items[0].extract_as_node();
assert_eq!(node.extract_as_element_node().name, "p");
}
#[test]
fn following_sibling_returns_all_following() {
let text = r#"<html><body><a>1</a><b>2</b><c>3</c><d>4</d></body></html>"#;
let document = html::parse(text).unwrap();
let xpath = xpath::parse("//b/following-sibling::*").unwrap();
let items = xpath.apply(&document).unwrap();
assert_eq!(items.len(), 2);
let names: Vec<&str> = items
.iter()
.map(|i| i.extract_as_node().extract_as_element_node().name.as_str())
.collect();
assert_eq!(names, vec!["c", "d"]);
}
#[test]
fn following_sibling_with_name_test() {
let text = r#"<html><body><a>1</a><b>2</b><a>3</a><c>4</c></body></html>"#;
let document = html::parse(text).unwrap();
let xpath = xpath::parse("//a[1]/following-sibling::a").unwrap();
let items = xpath.apply(&document).unwrap();
assert_eq!(items.len(), 1);
let node = items[0].extract_as_node();
assert_eq!(node.extract_as_element_node().name, "a");
}
#[test]
fn following_sibling_of_last_is_empty() {
let text = r#"<html><body><a>1</a><b>2</b></body></html>"#;
let document = html::parse(text).unwrap();
let xpath = xpath::parse("//b/following-sibling::*").unwrap();
let items = xpath.apply(&document).unwrap();
assert_eq!(items.len(), 0);
}
#[test]
fn following_axis_returns_all_following_nodes() {
let text = r#"<html><body><div><a>1</a></div><p>2</p><span>3</span></body></html>"#;
let document = html::parse(text).unwrap();
let xpath = xpath::parse("//a/following::*").unwrap();
let items = xpath.apply(&document).unwrap();
let names: Vec<&str> = items
.iter()
.filter_map(|i| match i {
XpathItem::Node(n) => Some(n.extract_as_element_node().name.as_str()),
_ => None,
})
.collect();
assert!(names.contains(&"p"));
assert!(names.contains(&"span"));
assert!(!names.contains(&"div"));
assert!(!names.contains(&"a"));
}
#[test]
fn following_axis_includes_descendants() {
let text =
r#"<html><body><a>1</a><div><p>inner</p></div></body></html>"#;
let document = html::parse(text).unwrap();
let xpath = xpath::parse("//a/following::p").unwrap();
let items = xpath.apply(&document).unwrap();
assert_eq!(items.len(), 1);
let node = items[0].extract_as_node();
assert_eq!(node.extract_as_element_node().name, "p");
}