NodeIterator.html (7359B)
1 <!doctype html> 2 <title>NodeIterator tests</title> 3 <link rel="author" title="Aryeh Gregor" href=ayg@aryeh.name> 4 <meta name=timeout content=long> 5 <div id=log></div> 6 <script src=/resources/testharness.js></script> 7 <script src=/resources/testharnessreport.js></script> 8 <script src=../common.js></script> 9 <script> 10 "use strict"; 11 12 function check_iter(iter, root, whatToShowValue) { 13 whatToShowValue = whatToShowValue === undefined ? 0xFFFFFFFF : whatToShowValue; 14 15 assert_equals(iter.toString(), '[object NodeIterator]', 'toString'); 16 assert_equals(iter.root, root, 'root'); 17 assert_equals(iter.whatToShow, whatToShowValue, 'whatToShow'); 18 assert_equals(iter.filter, null, 'filter'); 19 assert_equals(iter.referenceNode, root, 'referenceNode'); 20 assert_equals(iter.pointerBeforeReferenceNode, true, 'pointerBeforeReferenceNode'); 21 assert_readonly(iter, 'root'); 22 assert_readonly(iter, 'whatToShow'); 23 assert_readonly(iter, 'filter'); 24 assert_readonly(iter, 'referenceNode'); 25 assert_readonly(iter, 'pointerBeforeReferenceNode'); 26 } 27 28 test(function() { 29 var iter = document.createNodeIterator(document); 30 iter.detach(); 31 iter.detach(); 32 }, "detach() should be a no-op"); 33 34 test(function() { 35 var iter = document.createNodeIterator(document); 36 check_iter(iter, document); 37 }, "createNodeIterator() parameter defaults"); 38 39 test(function() { 40 var iter = document.createNodeIterator(document, null, null); 41 check_iter(iter, document, 0); 42 }, "createNodeIterator() with null as arguments"); 43 44 test(function() { 45 var iter = document.createNodeIterator(document, undefined, undefined); 46 check_iter(iter, document); 47 }, "createNodeIterator() with undefined as arguments"); 48 49 test(function() { 50 var err = {name: "failed"}; 51 var iter = document.createNodeIterator(document, NodeFilter.SHOW_ALL, 52 function() { throw err; }); 53 assert_throws_exactly(err, function() { iter.nextNode() }); 54 }, "Propagate exception from filter function"); 55 56 test(function() { 57 var depth = 0; 58 var iter = document.createNodeIterator(document, NodeFilter.SHOW_ALL, 59 function() { 60 if (iter.referenceNode != document && depth == 0) { 61 depth++; 62 iter.nextNode(); 63 } 64 return NodeFilter.FILTER_ACCEPT; 65 }); 66 iter.nextNode(); 67 iter.nextNode(); 68 assert_throws_dom("InvalidStateError", function() { iter.nextNode() }); 69 depth--; 70 assert_throws_dom("InvalidStateError", function() { iter.previousNode() }); 71 }, "Recursive filters need to throw"); 72 73 function testIterator(root, whatToShow, filter) { 74 var iter = document.createNodeIterator(root, whatToShow, filter); 75 76 assert_equals(iter.root, root, ".root"); 77 assert_equals(iter.referenceNode, root, "Initial .referenceNode"); 78 assert_equals(iter.pointerBeforeReferenceNode, true, 79 ".pointerBeforeReferenceNode"); 80 assert_equals(iter.whatToShow, whatToShow, ".whatToShow"); 81 assert_equals(iter.filter, filter, ".filter"); 82 83 var expectedReferenceNode = root; 84 var expectedBeforeNode = true; 85 // "Let node be the value of the referenceNode attribute." 86 var node = root; 87 // "Let before node be the value of the pointerBeforeReferenceNode 88 // attribute." 89 var beforeNode = true; 90 var i = 1; 91 // Each loop iteration runs nextNode() once. 92 while (node) { 93 do { 94 if (!beforeNode) { 95 // "If before node is false, let node be the first node following node 96 // in the iterator collection. If there is no such node return null." 97 node = nextNode(node); 98 if (!isInclusiveDescendant(node, root)) { 99 node = null; 100 break; 101 } 102 } else { 103 // "If before node is true, set it to false." 104 beforeNode = false; 105 } 106 // "Filter node and let result be the return value. 107 // 108 // "If result is FILTER_ACCEPT, go to the next step in the overall set of 109 // steps. 110 // 111 // "Otherwise, run these substeps again." 112 if (!((1 << (node.nodeType - 1)) & whatToShow) 113 || (filter && filter(node) != NodeFilter.FILTER_ACCEPT)) { 114 continue; 115 } 116 117 // "Set the referenceNode attribute to node, set the 118 // pointerBeforeReferenceNode attribute to before node, and return node." 119 expectedReferenceNode = node; 120 expectedBeforeNode = beforeNode; 121 122 break; 123 } while (true); 124 125 assert_equals(iter.nextNode(), node, ".nextNode() " + i + " time(s)"); 126 assert_equals(iter.referenceNode, expectedReferenceNode, 127 ".referenceNode after nextNode() " + i + " time(s)"); 128 assert_equals(iter.pointerBeforeReferenceNode, expectedBeforeNode, 129 ".pointerBeforeReferenceNode after nextNode() " + i + " time(s)"); 130 131 i++; 132 } 133 134 // Same but for previousNode() (mostly copy-pasted, oh well) 135 var iter = document.createNodeIterator(root, whatToShow, filter); 136 137 var expectedReferenceNode = root; 138 var expectedBeforeNode = true; 139 // "Let node be the value of the referenceNode attribute." 140 var node = root; 141 // "Let before node be the value of the pointerBeforeReferenceNode 142 // attribute." 143 var beforeNode = true; 144 var i = 1; 145 // Each loop iteration runs previousNode() once. 146 while (node) { 147 do { 148 if (beforeNode) { 149 // "If before node is true, let node be the first node preceding node 150 // in the iterator collection. If there is no such node return null." 151 node = previousNode(node); 152 if (!isInclusiveDescendant(node, root)) { 153 node = null; 154 break; 155 } 156 } else { 157 // "If before node is false, set it to true." 158 beforeNode = true; 159 } 160 // "Filter node and let result be the return value. 161 // 162 // "If result is FILTER_ACCEPT, go to the next step in the overall set of 163 // steps. 164 // 165 // "Otherwise, run these substeps again." 166 if (!((1 << (node.nodeType - 1)) & whatToShow) 167 || (filter && filter(node) != NodeFilter.FILTER_ACCEPT)) { 168 continue; 169 } 170 171 // "Set the referenceNode attribute to node, set the 172 // pointerBeforeReferenceNode attribute to before node, and return node." 173 expectedReferenceNode = node; 174 expectedBeforeNode = beforeNode; 175 176 break; 177 } while (true); 178 179 assert_equals(iter.previousNode(), node, ".previousNode() " + i + " time(s)"); 180 assert_equals(iter.referenceNode, expectedReferenceNode, 181 ".referenceNode after previousNode() " + i + " time(s)"); 182 assert_equals(iter.pointerBeforeReferenceNode, expectedBeforeNode, 183 ".pointerBeforeReferenceNode after previousNode() " + i + " time(s)"); 184 185 i++; 186 } 187 } 188 189 var whatToShows = [ 190 "0", 191 "0xFFFFFFFF", 192 "NodeFilter.SHOW_ELEMENT", 193 "NodeFilter.SHOW_ATTRIBUTE", 194 "NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_DOCUMENT", 195 ]; 196 197 var callbacks = [ 198 "null", 199 "(function(node) { return true })", 200 "(function(node) { return false })", 201 "(function(node) { return node.nodeName[0] == '#' })", 202 ]; 203 204 for (var i = 0; i < testNodes.length; i++) { 205 for (var j = 0; j < whatToShows.length; j++) { 206 for (var k = 0; k < callbacks.length; k++) { 207 test(() => { 208 testIterator(eval(testNodes[i]), eval(whatToShows[j]), eval(callbacks[k])); 209 }, "document.createNodeIterator(" + testNodes[i] + ", " + whatToShows[j] + ", " + callbacks[k] + ")"); 210 } 211 } 212 } 213 214 testDiv.style.display = "none"; 215 </script>