677858d2a51c03de1f120a97679740e00fdb6af5
[WebKit-https.git] / LayoutTests / imported / w3c / web-platform-tests / dom / traversal / NodeIterator.html
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 iter = document.createNodeIterator(document, NodeFilter.SHOW_ALL,
51                                         function() { throw {name: "failed"} });
52   assert_throws({name: "failed"}, function() { iter.nextNode() });
53 }, "Propagate exception from filter function");
54
55 test(function() {
56   var depth = 0;
57   var iter = document.createNodeIterator(document, NodeFilter.SHOW_ALL,
58     function() {
59       if (iter.referenceNode != document && depth == 0) {
60         depth++;
61         iter.nextNode();
62       }
63       return NodeFilter.FILTER_ACCEPT;
64     });
65   iter.nextNode();
66   iter.nextNode();
67   assert_throws("InvalidStateError", function() { iter.nextNode() });
68   depth--;
69   assert_throws("InvalidStateError", function() { iter.previousNode() });
70 }, "Recursive filters need to throw");
71
72 function testIterator(root, whatToShow, filter) {
73   var iter = document.createNodeIterator(root, whatToShow, filter);
74
75   assert_equals(iter.root, root, ".root");
76   assert_equals(iter.referenceNode, root, "Initial .referenceNode");
77   assert_equals(iter.pointerBeforeReferenceNode, true,
78                 ".pointerBeforeReferenceNode");
79   assert_equals(iter.whatToShow, whatToShow, ".whatToShow");
80   assert_equals(iter.filter, filter, ".filter");
81
82   var expectedReferenceNode = root;
83   var expectedBeforeNode = true;
84   // "Let node be the value of the referenceNode attribute."
85   var node = root;
86   // "Let before node be the value of the pointerBeforeReferenceNode
87   // attribute."
88   var beforeNode = true;
89   var i = 1;
90   // Each loop iteration runs nextNode() once.
91   while (node) {
92     do {
93       if (!beforeNode) {
94         // "If before node is false, let node be the first node following node
95         // in the iterator collection. If there is no such node return null."
96         node = nextNode(node);
97         if (!isInclusiveDescendant(node, root)) {
98           node = null;
99           break;
100         }
101       } else {
102         // "If before node is true, set it to false."
103         beforeNode = false;
104       }
105       // "Filter node and let result be the return value.
106       //
107       // "If result is FILTER_ACCEPT, go to the next step in the overall set of
108       // steps.
109       //
110       // "Otherwise, run these substeps again."
111       if (!((1 << (node.nodeType - 1)) & whatToShow)
112           || (filter && filter(node) != NodeFilter.FILTER_ACCEPT)) {
113         continue;
114       }
115
116       // "Set the referenceNode attribute to node, set the
117       // pointerBeforeReferenceNode attribute to before node, and return node."
118       expectedReferenceNode = node;
119       expectedBeforeNode = beforeNode;
120
121       break;
122     } while (true);
123
124     assert_equals(iter.nextNode(), node, ".nextNode() " + i + " time(s)");
125     assert_equals(iter.referenceNode, expectedReferenceNode,
126                   ".referenceNode after nextNode() " + i + " time(s)");
127     assert_equals(iter.pointerBeforeReferenceNode, expectedBeforeNode,
128              ".pointerBeforeReferenceNode after nextNode() " + i + " time(s)");
129
130     i++;
131   }
132
133   // Same but for previousNode() (mostly copy-pasted, oh well)
134   var iter = document.createNodeIterator(root, whatToShow, filter);
135
136   var expectedReferenceNode = root;
137   var expectedBeforeNode = true;
138   // "Let node be the value of the referenceNode attribute."
139   var node = root;
140   // "Let before node be the value of the pointerBeforeReferenceNode
141   // attribute."
142   var beforeNode = true;
143   var i = 1;
144   // Each loop iteration runs previousNode() once.
145   while (node) {
146     do {
147       if (beforeNode) {
148         // "If before node is true, let node be the first node preceding node
149         // in the iterator collection. If there is no such node return null."
150         node = previousNode(node);
151         if (!isInclusiveDescendant(node, root)) {
152           node = null;
153           break;
154         }
155       } else {
156         // "If before node is false, set it to true."
157         beforeNode = true;
158       }
159       // "Filter node and let result be the return value.
160       //
161       // "If result is FILTER_ACCEPT, go to the next step in the overall set of
162       // steps.
163       //
164       // "Otherwise, run these substeps again."
165       if (!((1 << (node.nodeType - 1)) & whatToShow)
166           || (filter && filter(node) != NodeFilter.FILTER_ACCEPT)) {
167         continue;
168       }
169
170       // "Set the referenceNode attribute to node, set the
171       // pointerBeforeReferenceNode attribute to before node, and return node."
172       expectedReferenceNode = node;
173       expectedBeforeNode = beforeNode;
174
175       break;
176     } while (true);
177
178     assert_equals(iter.previousNode(), node, ".previousNode() " + i + " time(s)");
179     assert_equals(iter.referenceNode, expectedReferenceNode,
180                   ".referenceNode after previousNode() " + i + " time(s)");
181     assert_equals(iter.pointerBeforeReferenceNode, expectedBeforeNode,
182          ".pointerBeforeReferenceNode after previousNode() " + i + " time(s)");
183
184     i++;
185   }
186 }
187
188 var whatToShows = [
189   "0",
190   "0xFFFFFFFF",
191   "NodeFilter.SHOW_ELEMENT",
192   "NodeFilter.SHOW_ATTRIBUTE",
193   "NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_DOCUMENT",
194 ];
195
196 var callbacks = [
197   "null",
198   "(function(node) { return true })",
199   "(function(node) { return false })",
200   "(function(node) { return node.nodeName[0] == '#' })",
201 ];
202
203 var tests = [];
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       tests.push([
208         "document.createNodeIterator(" + testNodes[i]
209           + ", " + whatToShows[j] + ", " + callbacks[k] + ")",
210         eval(testNodes[i]), eval(whatToShows[j]), eval(callbacks[k])
211       ]);
212     }
213   }
214 }
215
216 generate_tests(testIterator, tests);
217
218 testDiv.style.display = "none";
219 </script>