mirror of
https://github.com/servo/servo.git
synced 2025-08-09 15:35:34 +01:00
add xpath id() function tests
Signed-off-by: Ville Lindholm <ville@lindholm.dev>
This commit is contained in:
parent
a1ed93d313
commit
3d9cefffab
5 changed files with 71 additions and 11 deletions
|
@ -54,7 +54,7 @@ impl TryFrom<u16> for XPathResultType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(JSTraceable, MallocSizeOf)]
|
#[derive(JSTraceable, MallocSizeOf, Debug)]
|
||||||
pub(crate) enum XPathResultValue {
|
pub(crate) enum XPathResultValue {
|
||||||
Boolean(bool),
|
Boolean(bool),
|
||||||
/// A IEEE-754 double-precision floating point number
|
/// A IEEE-754 double-precision floating point number
|
||||||
|
|
|
@ -165,10 +165,13 @@ impl Evaluatable for CoreFunction {
|
||||||
let args = args_normalized.split(' ');
|
let args = args_normalized.split(' ');
|
||||||
|
|
||||||
let document = context.context_node.owner_doc();
|
let document = context.context_node.owner_doc();
|
||||||
let result = args
|
let mut result = Vec::new();
|
||||||
.flat_map(|arg| document.get_element_by_id(&Atom::from(arg)))
|
for arg in args {
|
||||||
.map(|e| DomRoot::from_ref(e.upcast::<Node>()));
|
for element in document.get_elements_with_id(&Atom::from(arg)).iter() {
|
||||||
Ok(Value::Nodeset(result.collect()))
|
result.push(DomRoot::from_ref(element.upcast::<Node>()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(Value::Nodeset(result))
|
||||||
},
|
},
|
||||||
CoreFunction::LocalName(expr_opt) => {
|
CoreFunction::LocalName(expr_opt) => {
|
||||||
let node = match expr_opt {
|
let node = match expr_opt {
|
||||||
|
|
|
@ -8,7 +8,6 @@ use std::{fmt, string};
|
||||||
|
|
||||||
use crate::dom::bindings::codegen::Bindings::NodeBinding::Node_Binding::NodeMethods;
|
use crate::dom::bindings::codegen::Bindings::NodeBinding::Node_Binding::NodeMethods;
|
||||||
use crate::dom::bindings::root::DomRoot;
|
use crate::dom::bindings::root::DomRoot;
|
||||||
use crate::dom::bindings::utils::AsVoidPtr;
|
|
||||||
use crate::dom::node::Node;
|
use crate::dom::node::Node;
|
||||||
|
|
||||||
/// The primary types of values that an XPath expression returns as a result.
|
/// The primary types of values that an XPath expression returns as a result.
|
||||||
|
@ -216,7 +215,7 @@ impl NodesetHelpers for Vec<DomRoot<Node>> {
|
||||||
}
|
}
|
||||||
fn document_order(&self) -> Vec<DomRoot<Node>> {
|
fn document_order(&self) -> Vec<DomRoot<Node>> {
|
||||||
let mut nodes: Vec<DomRoot<Node>> = self.clone();
|
let mut nodes: Vec<DomRoot<Node>> = self.clone();
|
||||||
if nodes.len() == 1 {
|
if nodes.len() <= 1 {
|
||||||
return nodes;
|
return nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,10 +232,13 @@ impl NodesetHelpers for Vec<DomRoot<Node>> {
|
||||||
nodes
|
nodes
|
||||||
}
|
}
|
||||||
fn document_order_unique(&self) -> Vec<DomRoot<Node>> {
|
fn document_order_unique(&self) -> Vec<DomRoot<Node>> {
|
||||||
let mut nodes: Vec<DomRoot<Node>> = self.document_order();
|
let mut seen = HashSet::new();
|
||||||
|
let unique_nodes: Vec<DomRoot<Node>> = self
|
||||||
|
.iter()
|
||||||
|
.filter(|node| seen.insert(node.to_opaque()))
|
||||||
|
.cloned()
|
||||||
|
.collect();
|
||||||
|
|
||||||
nodes.dedup_by_key(|n| n.as_void_ptr());
|
unique_nodes.document_order()
|
||||||
|
|
||||||
nodes
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
7
tests/wpt/meta/MANIFEST.json
vendored
7
tests/wpt/meta/MANIFEST.json
vendored
|
@ -630517,6 +630517,13 @@
|
||||||
{}
|
{}
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
"fn-id.html": [
|
||||||
|
"304d38985a0cf2df8b4365cae497292ef36d3599",
|
||||||
|
[
|
||||||
|
null,
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
"fn-lang.html": [
|
"fn-lang.html": [
|
||||||
"1fbd0a2ee4d419275c6d78f54e3425135cf838a1",
|
"1fbd0a2ee4d419275c6d78f54e3425135cf838a1",
|
||||||
[
|
[
|
||||||
|
|
48
tests/wpt/tests/domxpath/fn-id.html
vendored
Normal file
48
tests/wpt/tests/domxpath/fn-id.html
vendored
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<link rel="help" href="https://www.w3.org/TR/1999/REC-xpath-19991116/#function-id">
|
||||||
|
<body>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script>
|
||||||
|
// Test the id() function with various scenarios
|
||||||
|
function testIdFunction(expression, xmlString, expectedIds) {
|
||||||
|
let doc = (new DOMParser()).parseFromString(xmlString, 'text/xml');
|
||||||
|
test(() => {
|
||||||
|
let result = doc.evaluate(expression, doc.documentElement, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
|
||||||
|
assert_equals(result.resultType, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);
|
||||||
|
|
||||||
|
let actualIds = [];
|
||||||
|
for (let i = 0; i < result.snapshotLength; i++) {
|
||||||
|
actualIds.push(result.snapshotItem(i).getAttribute('id'));
|
||||||
|
}
|
||||||
|
actualIds.sort();
|
||||||
|
expectedIds.sort();
|
||||||
|
assert_array_equals(actualIds, expectedIds, `Expected IDs ${expectedIds}, got ${actualIds}`);
|
||||||
|
}, `${expression}: ${doc.documentElement.outerHTML}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test single ID
|
||||||
|
testIdFunction('id("test1")', '<root><div id="test1">Match</div></root>', ['test1']);
|
||||||
|
|
||||||
|
// Test multiple IDs in space-separated string
|
||||||
|
testIdFunction('id("test1 test2")', '<root><div id="test1">First</div><div id="test2">Second</div></root>', ['test1', 'test2']);
|
||||||
|
|
||||||
|
// Test non-existent ID
|
||||||
|
testIdFunction('id("nonexistent")', '<root><div id="test1">No match</div></root>', []);
|
||||||
|
|
||||||
|
// Test mixed case IDs (should be case-sensitive)
|
||||||
|
testIdFunction('id("Test1")', '<root><div id="test1">No match</div></root>', []);
|
||||||
|
|
||||||
|
// Test multiple elements with same ID (should return all)
|
||||||
|
testIdFunction('id("duplicate")', '<root><div id="duplicate">First</div><div id="duplicate">Second</div></root>', ['duplicate', 'duplicate']);
|
||||||
|
|
||||||
|
// Test IDs with special characters
|
||||||
|
testIdFunction('id("test-1")', '<root><div id="test-1">Match</div></root>', ['test-1']);
|
||||||
|
|
||||||
|
// Test empty ID string
|
||||||
|
testIdFunction('id("")', '<root><div id="">Empty ID</div></root>', []);
|
||||||
|
|
||||||
|
// Test whitespace in ID string
|
||||||
|
testIdFunction('id(" test1 ")', '<root><div id="test1">Match</div></root>', ['test1']);
|
||||||
|
</script>
|
||||||
|
</body>
|
Loading…
Add table
Add a link
Reference in a new issue