Bug 1885602 - Part 5: Implement navigating to the SUMO help topic from the menu heade...
[gecko.git] / dom / bindings / test / test_iterable.html
blob4c2dc0fc4e174cb8056a42aa0ff868dc26d6aa6d
1 <!-- Any copyright is dedicated to the Public Domain.
2 - http://creativecommons.org/publicdomain/zero/1.0/ -->
3 <!DOCTYPE HTML>
4 <html>
5 <head>
6 <title>Test Iterable Interface</title>
7 <script src="/tests/SimpleTest/SimpleTest.js"></script>
8 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
9 </head>
10 <body>
11 <script class="testbody" type="application/javascript">
12 /* global TestInterfaceIterableSingle, TestInterfaceIterableDouble, TestInterfaceIterableDoubleUnion */
14 SimpleTest.waitForExplicitFinish();
15 SpecialPowers.pushPrefEnv({set: [["dom.expose_test_interfaces", true]]}, function() {
16 var base_properties = [["entries", "function", 0],
17 ["keys", "function", 0],
18 ["values", "function", 0],
19 ["forEach", "function", 1]];
20 var testExistence = function testExistence(prefix, obj, properties) {
21 for (var [name, type, args] of properties) {
22 // Properties are somewhere up the proto chain, hasOwnProperty won't work
23 isnot(obj[name], undefined,
24 `${prefix} object has property ${name}`);
26 is(typeof obj[name], type,
27 `${prefix} object property ${name} is a ${type}`);
28 // Check function length
29 if (type == "function") {
30 is(obj[name].length, args,
31 `${prefix} object property ${name} is length ${args}`);
32 is(obj[name].name, name,
33 `${prefix} object method name is ${name}`);
36 // Find where property is on proto chain, check for enumerablility there.
37 var owner = obj;
38 while (owner) {
39 var propDesc = Object.getOwnPropertyDescriptor(owner, name);
40 if (propDesc) {
41 ok(propDesc.enumerable,
42 `${prefix} object property ${name} is enumerable`);
43 break;
45 owner = Object.getPrototypeOf(owner);
50 var itr;
51 info("IterableSingle: Testing simple iterable creation and functionality");
52 itr = new TestInterfaceIterableSingle();
53 testExistence("IterableSingle: ", itr, base_properties);
54 is(itr[Symbol.iterator], Array.prototype[Symbol.iterator],
55 "IterableSingle: Should be using %ArrayIterator% for @@iterator");
56 is(itr.keys, Array.prototype.keys,
57 "IterableSingle: Should be using %ArrayIterator% for 'keys'");
58 is(itr.entries, Array.prototype.entries,
59 "IterableSingle: Should be using %ArrayIterator% for 'entries'");
60 is(itr.values, itr[Symbol.iterator],
61 "IterableSingle: Should be using @@iterator for 'values'");
62 is(itr.forEach, Array.prototype.forEach,
63 "IterableSingle: Should be using %ArrayIterator% for 'forEach'");
64 var keys = [...itr.keys()];
65 var values = [...itr.values()];
66 var entries = [...itr.entries()];
67 var key_itr = itr.keys();
68 var value_itr = itr.values();
69 var entries_itr = itr.entries();
70 for (let i = 0; i < 3; ++i) {
71 let key = key_itr.next();
72 let value = value_itr.next();
73 let entry = entries_itr.next();
74 is(key.value, i, "IterableSingle: Key iterator value should be " + i);
75 is(key.value, keys[i],
76 "IterableSingle: Key iterator value should match destructuring " + i);
77 is(value.value, key.value, "IterableSingle: Value iterator value should be " + key.value);
78 is(value.value, values[i],
79 "IterableSingle: Value iterator value should match destructuring " + i);
80 is(entry.value[0], i, "IterableSingle: Entry iterator value 0 should be " + i);
81 is(entry.value[1], i, "IterableSingle: Entry iterator value 1 should be " + i);
82 is(entry.value[0], entries[i][0],
83 "IterableSingle: Entry iterator value 0 should match destructuring " + i);
84 is(entry.value[1], entries[i][1],
85 "IterableSingle: Entry iterator value 1 should match destructuring " + i);
88 var callsToForEachCallback = 0;
89 var thisArg = {};
90 itr.forEach(function(value1, index, obj) {
91 is(index, callsToForEachCallback,
92 `IterableSingle: Should have the right index at ${callsToForEachCallback} calls to forEach callback`);
93 is(value1, values[index],
94 `IterableSingle: Should have the right value at ${callsToForEachCallback} calls to forEach callback`);
95 is(this, thisArg,
96 "IterableSingle: Should have the right this value for forEach callback");
97 is(obj, itr,
98 "IterableSingle: Should have the right third arg for forEach callback");
99 ++callsToForEachCallback;
100 }, thisArg);
101 is(callsToForEachCallback, 3,
102 "IterableSingle: Should have right total number of calls to forEach callback");
104 let key = key_itr.next();
105 let value = value_itr.next();
106 let entry = entries_itr.next();
107 is(key.value, undefined, "IterableSingle: Key iterator value should be undefined");
108 is(key.done, true, "IterableSingle: Key iterator done should be true");
109 is(value.value, undefined, "IterableSingle: Value iterator value should be undefined");
110 is(value.done, true, "IterableSingle: Value iterator done should be true");
111 is(entry.value, undefined, "IterableDouble: Entry iterator value should be undefined");
112 is(entry.done, true, "IterableSingle: Entry iterator done should be true");
113 is(Object.prototype.toString.call(Object.getPrototypeOf(key_itr)),
114 "[object Array Iterator]",
115 "iterator prototype should have the right brand");
117 // Simple dual type iterable creation and functionality test
118 info("IterableDouble: Testing simple iterable creation and functionality");
119 itr = new TestInterfaceIterableDouble();
120 testExistence("IterableDouble: ", itr, base_properties);
121 is(itr.entries, itr[Symbol.iterator],
122 "IterableDouble: Should be using @@iterator for 'entries'");
123 var elements = [["a", "b"], ["c", "d"], ["e", "f"]];
124 keys = [...itr.keys()];
125 values = [...itr.values()];
126 entries = [...itr.entries()];
127 key_itr = itr.keys();
128 value_itr = itr.values();
129 entries_itr = itr.entries();
130 for (let i = 0; i < 3; ++i) {
131 key = key_itr.next();
132 value = value_itr.next();
133 entry = entries_itr.next();
134 is(key.value, elements[i][0], "IterableDouble: Key iterator value should be " + elements[i][0]);
135 is(key.value, keys[i],
136 "IterableDouble: Key iterator value should match destructuring " + i);
137 is(value.value, elements[i][1], "IterableDouble: Value iterator value should be " + elements[i][1]);
138 is(value.value, values[i],
139 "IterableDouble: Value iterator value should match destructuring " + i);
140 is(entry.value[0], elements[i][0], "IterableDouble: Entry iterator value 0 should be " + elements[i][0]);
141 is(entry.value[1], elements[i][1], "IterableDouble: Entry iterator value 1 should be " + elements[i][1]);
142 is(entry.value[0], entries[i][0],
143 "IterableDouble: Entry iterator value 0 should match destructuring " + i);
144 is(entry.value[1], entries[i][1],
145 "IterableDouble: Entry iterator value 1 should match destructuring " + i);
148 callsToForEachCallback = 0;
149 thisArg = {};
150 itr.forEach(function(value1, key1, obj) {
151 is(key1, keys[callsToForEachCallback],
152 `IterableDouble: Should have the right key at ${callsToForEachCallback} calls to forEach callback`);
153 is(value1, values[callsToForEachCallback],
154 `IterableDouble: Should have the right value at ${callsToForEachCallback} calls to forEach callback`);
155 is(this, thisArg,
156 "IterableDouble: Should have the right this value for forEach callback");
157 is(obj, itr,
158 "IterableSingle: Should have the right third arg for forEach callback");
159 ++callsToForEachCallback;
160 }, thisArg);
161 is(callsToForEachCallback, 3,
162 "IterableDouble: Should have right total number of calls to forEach callback");
164 key = key_itr.next();
165 value = value_itr.next();
166 entry = entries_itr.next();
167 is(key.value, undefined, "IterableDouble: Key iterator value should be undefined");
168 is(key.done, true, "IterableDouble: Key iterator done should be true");
169 is(value.value, undefined, "IterableDouble: Value iterator value should be undefined");
170 is(value.done, true, "IterableDouble: Value iterator done should be true");
171 is(entry.value, undefined, "IterableDouble: Entry iterator value should be undefined");
172 is(entry.done, true, "IterableDouble: Entry iterator done should be true");
173 is(Object.prototype.toString.call(Object.getPrototypeOf(key_itr)),
174 "[object TestInterfaceIterableDouble Iterator]",
175 "iterator prototype should have the right brand");
177 // Simple dual type iterable creation and functionality test
178 info("IterableDoubleUnion: Testing simple iterable creation and functionality");
179 itr = new TestInterfaceIterableDoubleUnion();
180 testExistence("IterableDoubleUnion: ", itr, base_properties);
181 is(itr.entries, itr[Symbol.iterator],
182 "IterableDoubleUnion: Should be using @@iterator for 'entries'");
183 elements = [["long", 1], ["string", "a"]];
184 keys = [...itr.keys()];
185 values = [...itr.values()];
186 entries = [...itr.entries()];
187 key_itr = itr.keys();
188 value_itr = itr.values();
189 entries_itr = itr.entries();
190 for (let i = 0; i < elements.length; ++i) {
191 key = key_itr.next();
192 value = value_itr.next();
193 entry = entries_itr.next();
194 is(key.value, elements[i][0], "IterableDoubleUnion: Key iterator value should be " + elements[i][0]);
195 is(key.value, keys[i],
196 "IterableDoubleUnion: Key iterator value should match destructuring " + i);
197 is(value.value, elements[i][1], "IterableDoubleUnion: Value iterator value should be " + elements[i][1]);
198 is(value.value, values[i],
199 "IterableDoubleUnion: Value iterator value should match destructuring " + i);
200 is(entry.value[0], elements[i][0], "IterableDoubleUnion: Entry iterator value 0 should be " + elements[i][0]);
201 is(entry.value[1], elements[i][1], "IterableDoubleUnion: Entry iterator value 1 should be " + elements[i][1]);
202 is(entry.value[0], entries[i][0],
203 "IterableDoubleUnion: Entry iterator value 0 should match destructuring " + i);
204 is(entry.value[1], entries[i][1],
205 "IterableDoubleUnion: Entry iterator value 1 should match destructuring " + i);
208 callsToForEachCallback = 0;
209 thisArg = {};
210 itr.forEach(function(value1, key1, obj) {
211 is(key1, keys[callsToForEachCallback],
212 `IterableDoubleUnion: Should have the right key at ${callsToForEachCallback} calls to forEach callback`);
213 is(value1, values[callsToForEachCallback],
214 `IterableDoubleUnion: Should have the right value at ${callsToForEachCallback} calls to forEach callback`);
215 is(this, thisArg,
216 "IterableDoubleUnion: Should have the right this value for forEach callback");
217 is(obj, itr,
218 "IterableSingle: Should have the right third arg for forEach callback");
219 ++callsToForEachCallback;
220 }, thisArg);
221 is(callsToForEachCallback, 2,
222 "IterableDoubleUnion: Should have right total number of calls to forEach callback");
224 key = key_itr.next();
225 value = value_itr.next();
226 entry = entries_itr.next();
227 is(key.value, undefined, "IterableDoubleUnion: Key iterator value should be undefined");
228 is(key.done, true, "IterableDoubleUnion: Key iterator done should be true");
229 is(value.value, undefined, "IterableDoubleUnion: Value iterator value should be undefined");
230 is(value.done, true, "IterableDoubleUnion: Value iterator done should be true");
231 is(entry.value, undefined, "IterableDoubleUnion: Entry iterator value should be undefined");
232 is(entry.done, true, "IterableDoubleUnion: Entry iterator done should be true");
233 is(Object.prototype.toString.call(Object.getPrototypeOf(key_itr)),
234 "[object TestInterfaceIterableDoubleUnion Iterator]",
235 "iterator prototype should have the right brand");
237 SimpleTest.finish();
239 </script>
240 </body>
241 </html>