use std::str::FromStr;
use crate::Document;
use super::*;
fn check_path(document: &Document, expression: &str, expected: &[&str]) {
let p1 = XPath::new(expression).unwrap();
let sequence = p1.apply(document).unwrap();
assert_eq!(sequence.items.len(), expected.len());
for (i, node) in sequence.items.iter().enumerate() {
let result = match node {
XPathValue::Node(cursor) => cursor.to_string(),
};
assert_eq!(result, expected[i]);
}
}
#[test]
fn simple_steps() {
let doc = Document::from_str(
"<a><b><b/></b><d><e>123</e><f>456<b i=\"1\"/>789</f><b>abc</b></d></a>",
)
.unwrap();
check_path(
&doc,
"/*",
&["<a><b><b/></b><d><e>123</e><f>456<b i=\"1\"/>789</f><b>abc</b></d></a>"],
);
check_path(
&doc,
"/a",
&["<a><b><b/></b><d><e>123</e><f>456<b i=\"1\"/>789</f><b>abc</b></d></a>"],
);
check_path(&doc, "/a/b", &["<b><b/></b>"]);
check_path(&doc, "/a/d/f/b", &["<b i=\"1\"/>"]);
check_path(
&doc,
"/a/d/*",
&["<e>123</e>", "<f>456<b i=\"1\"/>789</f>", "<b>abc</b>"],
);
check_path(
&doc,
"//b",
&["<b><b/></b>", "<b/>", "<b i=\"1\"/>", "<b>abc</b>"],
);
check_path(&doc, "/a/d//b", &["<b i=\"1\"/>", "<b>abc</b>"]);
check_path(&doc, "//b/b", &["<b/>"]);
}
#[test]
fn predicates() {
let doc = Document::from_str(
"<a><b><c id='1'/></b><d><c id='2'>123</c></d><b><x id='1'/><c id='2'/></b></a>",
)
.unwrap();
check_path(&doc, "/a/*[1]", &["<b><c id=\"1\"/></b>"]);
check_path(&doc, "/a/*[2]", &["<d><c id=\"2\">123</c></d>"]);
check_path(
&doc,
"//c[@id=2]",
&["<c id=\"2\">123</c>", "<c id=\"2\"/>"],
);
check_path(&doc, "//*[@id=1]", &["<c id=\"1\"/>", "<x id=\"1\"/>"]);
check_path(
&doc,
"//*[@id]",
&[
"<c id=\"1\"/>",
"<c id=\"2\">123</c>",
"<x id=\"1\"/>",
"<c id=\"2\"/>",
],
);
}