1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
|
<!DOCTYPE html>
<html>
<head>
<title>Invalidation of iterators over XPath results</title>
<link rel="author" title="Simon Wülker" href="mailto:simon.wuelker@arcor.de">
<link rel="help" href="https://www.w3.org/TR/DOM-Level-3-XPath/xpath.html#XPathResult-iterateNext">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<ul id="list">
<li id="first-child"></li>
<li id="second-child"></li>
</ul>
<script>
function make_xpath_query(result_type) {
return document.evaluate(
"//li",
document,
null,
result_type,
null
);
}
function invalidate_iterator(test) {
let new_element = document.createElement("li");
document.getElementById("list").appendChild(new_element);
test.add_cleanup(() => {
new_element.remove();
})
}
test((t) => {
let iterator = make_xpath_query(XPathResult.ORDERED_NODE_ITERATOR_TYPE);
assert_equals(iterator.iterateNext(), document.getElementById("first-child"));
assert_equals(iterator.iterateNext(), document.getElementById("second-child"));
assert_equals(iterator.iterateNext(), null);
assert_false(iterator.invalidIteratorState);
}, "Using an ordered iterator without modifying the dom should yield the expected elements in correct order without errors.");
test((t) => {
let iterator = make_xpath_query(XPathResult.UNORDERED_NODE_ITERATOR_TYPE);
assert_not_equals(iterator.iterateNext(), null);
assert_not_equals(iterator.iterateNext(), null);
assert_equals(iterator.iterateNext(), null);
assert_false(iterator.invalidIteratorState);
}, "Using an unordered iterator without modifying the dom should yield the correct number of elements without errors.");
test((t) => {
let non_iterator_query = make_xpath_query(XPathResult.BOOLEAN_TYPE);
assert_false(non_iterator_query.invalidIteratorState);
invalidate_iterator(t);
assert_false(non_iterator_query.invalidIteratorState);
}, "invalidIteratorState should be false for non-iterable results.");
test((t) => {
let non_iterator_query = make_xpath_query(XPathResult.BOOLEAN_TYPE);
assert_throws_js(TypeError, () => non_iterator_query.iterateNext());
}, "Calling iterateNext on a non-iterable XPathResult should throw a TypeError.");
test((t) => {
let non_iterator_query = make_xpath_query(XPathResult.BOOLEAN_TYPE);
invalidate_iterator(t);
assert_throws_js(TypeError, () => non_iterator_query.iterateNext());
}, "Calling iterateNext on a non-iterable XPathResult after modifying the DOM should throw a TypeError.");
test((t) => {
let iterator = make_xpath_query(XPathResult.ORDERED_NODE_ITERATOR_TYPE);
iterator.iterateNext();
invalidate_iterator(t);
assert_throws_dom(
"InvalidStateError",
() => iterator.iterateNext(),
);
}, "Calling iterateNext after having modified the DOM should throw an exception.");
test((t) => {
let iterator = make_xpath_query(XPathResult.ORDERED_NODE_ITERATOR_TYPE);
iterator.iterateNext();
iterator.iterateNext();
invalidate_iterator(t);
assert_throws_dom(
"InvalidStateError",
() => iterator.iterateNext(),
);
}, "Calling iterateNext after having modified the DOM should throw an exception even if the iterator is exhausted.");
</script>
</body>
</html>
|