| <!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> |