| <!doctype html> |
| <title>NodeIterator tests</title> |
| <link rel="author" title="Aryeh Gregor" href=ayg@aryeh.name> |
| <meta name=timeout content=long> |
| <div id=log></div> |
| <script src=/resources/testharness.js></script> |
| <script src=/resources/testharnessreport.js></script> |
| <script src=../common.js></script> |
| <script> |
| "use strict"; |
| |
| function check_iter(iter, root, whatToShowValue) { |
| whatToShowValue = whatToShowValue === undefined ? 0xFFFFFFFF : whatToShowValue; |
| |
| assert_equals(iter.toString(), '[object NodeIterator]', 'toString'); |
| assert_equals(iter.root, root, 'root'); |
| assert_equals(iter.whatToShow, whatToShowValue, 'whatToShow'); |
| assert_equals(iter.filter, null, 'filter'); |
| assert_equals(iter.referenceNode, root, 'referenceNode'); |
| assert_equals(iter.pointerBeforeReferenceNode, true, 'pointerBeforeReferenceNode'); |
| assert_readonly(iter, 'root'); |
| assert_readonly(iter, 'whatToShow'); |
| assert_readonly(iter, 'filter'); |
| assert_readonly(iter, 'referenceNode'); |
| assert_readonly(iter, 'pointerBeforeReferenceNode'); |
| } |
| |
| test(function() { |
| var iter = document.createNodeIterator(document); |
| iter.detach(); |
| iter.detach(); |
| }, "detach() should be a no-op"); |
| |
| test(function() { |
| var iter = document.createNodeIterator(document); |
| check_iter(iter, document); |
| }, "createNodeIterator() parameter defaults"); |
| |
| test(function() { |
| var iter = document.createNodeIterator(document, null, null); |
| check_iter(iter, document, 0); |
| }, "createNodeIterator() with null as arguments"); |
| |
| test(function() { |
| var iter = document.createNodeIterator(document, undefined, undefined); |
| check_iter(iter, document); |
| }, "createNodeIterator() with undefined as arguments"); |
| |
| test(function() { |
| var iter = document.createNodeIterator(document, NodeFilter.SHOW_ALL, |
| function() { throw {name: "failed"} }); |
| assert_throws({name: "failed"}, function() { iter.nextNode() }); |
| }, "Propagate exception from filter function"); |
| |
| function testIterator(root, whatToShow, filter) { |
| var iter = document.createNodeIterator(root, whatToShow, filter); |
| |
| assert_equals(iter.root, root, ".root"); |
| assert_equals(iter.referenceNode, root, "Initial .referenceNode"); |
| assert_equals(iter.pointerBeforeReferenceNode, true, |
| ".pointerBeforeReferenceNode"); |
| assert_equals(iter.whatToShow, whatToShow, ".whatToShow"); |
| assert_equals(iter.filter, filter, ".filter"); |
| |
| var expectedReferenceNode = root; |
| var expectedBeforeNode = true; |
| // "Let node be the value of the referenceNode attribute." |
| var node = root; |
| // "Let before node be the value of the pointerBeforeReferenceNode |
| // attribute." |
| var beforeNode = true; |
| var i = 1; |
| // Each loop iteration runs nextNode() once. |
| while (node) { |
| do { |
| if (!beforeNode) { |
| // "If before node is false, let node be the first node following node |
| // in the iterator collection. If there is no such node return null." |
| node = nextNode(node); |
| if (!isInclusiveDescendant(node, root)) { |
| node = null; |
| break; |
| } |
| } else { |
| // "If before node is true, set it to false." |
| beforeNode = false; |
| } |
| // "Filter node and let result be the return value. |
| // |
| // "If result is FILTER_ACCEPT, go to the next step in the overall set of |
| // steps. |
| // |
| // "Otherwise, run these substeps again." |
| if (!((1 << (node.nodeType - 1)) & whatToShow) |
| || (filter && filter(node) != NodeFilter.FILTER_ACCEPT)) { |
| continue; |
| } |
| |
| // "Set the referenceNode attribute to node, set the |
| // pointerBeforeReferenceNode attribute to before node, and return node." |
| expectedReferenceNode = node; |
| expectedBeforeNode = beforeNode; |
| |
| break; |
| } while (true); |
| |
| assert_equals(iter.nextNode(), node, ".nextNode() " + i + " time(s)"); |
| assert_equals(iter.referenceNode, expectedReferenceNode, |
| ".referenceNode after nextNode() " + i + " time(s)"); |
| assert_equals(iter.pointerBeforeReferenceNode, expectedBeforeNode, |
| ".pointerBeforeReferenceNode after nextNode() " + i + " time(s)"); |
| |
| i++; |
| } |
| |
| // Same but for previousNode() (mostly copy-pasted, oh well) |
| var iter = document.createNodeIterator(root, whatToShow, filter); |
| |
| var expectedReferenceNode = root; |
| var expectedBeforeNode = true; |
| // "Let node be the value of the referenceNode attribute." |
| var node = root; |
| // "Let before node be the value of the pointerBeforeReferenceNode |
| // attribute." |
| var beforeNode = true; |
| var i = 1; |
| // Each loop iteration runs previousNode() once. |
| while (node) { |
| do { |
| if (beforeNode) { |
| // "If before node is true, let node be the first node preceding node |
| // in the iterator collection. If there is no such node return null." |
| node = previousNode(node); |
| if (!isInclusiveDescendant(node, root)) { |
| node = null; |
| break; |
| } |
| } else { |
| // "If before node is false, set it to true." |
| beforeNode = true; |
| } |
| // "Filter node and let result be the return value. |
| // |
| // "If result is FILTER_ACCEPT, go to the next step in the overall set of |
| // steps. |
| // |
| // "Otherwise, run these substeps again." |
| if (!((1 << (node.nodeType - 1)) & whatToShow) |
| || (filter && filter(node) != NodeFilter.FILTER_ACCEPT)) { |
| continue; |
| } |
| |
| // "Set the referenceNode attribute to node, set the |
| // pointerBeforeReferenceNode attribute to before node, and return node." |
| expectedReferenceNode = node; |
| expectedBeforeNode = beforeNode; |
| |
| break; |
| } while (true); |
| |
| assert_equals(iter.previousNode(), node, ".previousNode() " + i + " time(s)"); |
| assert_equals(iter.referenceNode, expectedReferenceNode, |
| ".referenceNode after previousNode() " + i + " time(s)"); |
| assert_equals(iter.pointerBeforeReferenceNode, expectedBeforeNode, |
| ".pointerBeforeReferenceNode after previousNode() " + i + " time(s)"); |
| |
| i++; |
| } |
| } |
| |
| var whatToShows = [ |
| "0", |
| "0xFFFFFFFF", |
| "NodeFilter.SHOW_ELEMENT", |
| "NodeFilter.SHOW_ATTRIBUTE", |
| "NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_DOCUMENT", |
| ]; |
| |
| var callbacks = [ |
| "null", |
| "(function(node) { return true })", |
| "(function(node) { return false })", |
| "(function(node) { return node.nodeName[0] == '#' })", |
| ]; |
| |
| var tests = []; |
| for (var i = 0; i < testNodes.length; i++) { |
| for (var j = 0; j < whatToShows.length; j++) { |
| for (var k = 0; k < callbacks.length; k++) { |
| tests.push([ |
| "document.createNodeIterator(" + testNodes[i] |
| + ", " + whatToShows[j] + ", " + callbacks[k] + ")", |
| eval(testNodes[i]), eval(whatToShows[j]), eval(callbacks[k]) |
| ]); |
| } |
| } |
| } |
| |
| generate_tests(testIterator, tests); |
| |
| testDiv.style.display = "none"; |
| </script> |