use skyscraper::{html, xpath};
#[test]
fn name_test_unprefixed() {
let text = r#"<html><body><div>hello</div></body></html>"#;
let document = html::parse(text).unwrap();
let xpath = xpath::parse("//div").unwrap();
let items = xpath.apply(&document).unwrap();
assert_eq!(items.len(), 1, "should match 1 div: {items:?}");
}
#[test]
fn wildcard_simple_matches_elements() {
let text = r#"<html><body><div>a</div><span>b</span></body></html>"#;
let document = html::parse(text).unwrap();
let xpath = xpath::parse("//body/*").unwrap();
let items = xpath.apply(&document).unwrap();
assert_eq!(items.len(), 2, "should match div and span: {items:?}");
}
#[test]
fn wildcard_prefixed_name_matches_local() {
let text = r#"<html><body><div>a</div><span>b</span></body></html>"#;
let document = html::parse(text).unwrap();
let xpath = xpath::parse("//body/*:div").unwrap();
let items = xpath.apply(&document).unwrap();
assert_eq!(items.len(), 1, "should match only div: {items:?}");
}
#[test]
fn wildcard_prefixed_name_no_match() {
let text = r#"<html><body><div>a</div></body></html>"#;
let document = html::parse(text).unwrap();
let xpath = xpath::parse("//body/*:span").unwrap();
let items = xpath.apply(&document).unwrap();
assert_eq!(items.len(), 0, "should match nothing: {items:?}");
}
#[test]
fn name_test_prefixed() {
let text = r#"<html><body><div>hello</div></body></html>"#;
let document = html::parse(text).unwrap();
let xpath = xpath::parse("//html:div").unwrap();
let items = xpath.apply(&document).unwrap();
assert_eq!(items.len(), 1, "should match 1 div: {items:?}");
}
#[test]
fn name_test_non_node_no_panic() {
let text = r#"<html><body></body></html>"#;
let document = html::parse(text).unwrap();
let xpath = xpath::parse("(1, 2, 3)/div").unwrap();
let result = xpath.apply(&document);
match result {
Ok(items) => assert_eq!(items.len(), 0, "atomic values have no children: {items:?}"),
Err(_) => {} }
}
#[test]
fn wildcard_svg_prefix_matches_svg_elements() {
let text = r#"<html><body><svg><rect/><circle/></svg><div>not svg</div></body></html>"#;
let document = html::parse(text).unwrap();
let xpath = xpath::parse("//svg:*").unwrap();
let items = xpath.apply(&document).unwrap();
assert_eq!(items.len(), 3, "should match svg, rect, circle: {items:?}");
for item in &items {
let el = item.extract_as_node().extract_as_element_node();
assert!(
["svg", "rect", "circle"].contains(&el.name.as_str()),
"unexpected element: {}",
el.name
);
}
}
#[test]
fn wildcard_svg_prefix_excludes_html_elements() {
let text = r#"<html><body><div>hello</div></body></html>"#;
let document = html::parse(text).unwrap();
let xpath = xpath::parse("//svg:*").unwrap();
let items = xpath.apply(&document).unwrap();
assert_eq!(items.len(), 0, "should not match any HTML elements: {items:?}");
}
#[test]
fn wildcard_html_prefix_matches_html_elements() {
let text = r#"<html><body><div>a</div><span>b</span></body></html>"#;
let document = html::parse(text).unwrap();
let xpath = xpath::parse("//body/html:*").unwrap();
let items = xpath.apply(&document).unwrap();
assert_eq!(items.len(), 2, "should match div and span: {items:?}");
}
#[test]
fn wildcard_html_prefix_excludes_svg_elements() {
let text = r#"<html><body><svg><rect/></svg></body></html>"#;
let document = html::parse(text).unwrap();
let xpath = xpath::parse("//svg/html:*").unwrap();
let items = xpath.apply(&document).unwrap();
assert_eq!(items.len(), 0, "should not match SVG elements: {items:?}");
}
#[test]
fn wildcard_mathml_prefix_matches_mathml_elements() {
let text = r#"<html><body><math><mi>x</mi><mo>+</mo><mn>1</mn></math></body></html>"#;
let document = html::parse(text).unwrap();
let xpath = xpath::parse("//mathml:*").unwrap();
let items = xpath.apply(&document).unwrap();
assert_eq!(items.len(), 4, "should match math, mi, mo, mn: {items:?}");
}
#[test]
fn wildcard_unknown_prefix_errors() {
let text = r#"<html><body><div>hello</div></body></html>"#;
let document = html::parse(text).unwrap();
let xpath = xpath::parse("//foo:*").unwrap();
let result = xpath.apply(&document);
assert!(result.is_err(), "unknown prefix should produce an error");
let err = result.unwrap_err().to_string();
assert!(
err.contains("XPST0081"),
"error should reference XPST0081: {err}"
);
}
#[test]
fn wildcard_braced_uri_svg_matches() {
let text = r#"<html><body><svg><rect/></svg></body></html>"#;
let document = html::parse(text).unwrap();
let xpath = xpath::parse("//Q{http://www.w3.org/2000/svg}*").unwrap();
let items = xpath.apply(&document).unwrap();
assert_eq!(items.len(), 2, "should match svg and rect: {items:?}");
}
#[test]
fn wildcard_braced_uri_html_matches() {
let text = r#"<html><body><div>a</div></body></html>"#;
let document = html::parse(text).unwrap();
let xpath = xpath::parse("//body/Q{http://www.w3.org/1999/xhtml}*").unwrap();
let items = xpath.apply(&document).unwrap();
assert_eq!(items.len(), 1, "should match div: {items:?}");
}
#[test]
fn wildcard_braced_uri_svg_excludes_html() {
let text = r#"<html><body><div>hello</div></body></html>"#;
let document = html::parse(text).unwrap();
let xpath = xpath::parse("//Q{http://www.w3.org/2000/svg}*").unwrap();
let items = xpath.apply(&document).unwrap();
assert_eq!(items.len(), 0, "should not match HTML elements: {items:?}");
}