test_iterable.html (12729B)
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 */ 13 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}`); 25 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}`); 34 } 35 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; 44 } 45 owner = Object.getPrototypeOf(owner); 46 } 47 } 48 }; 49 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); 86 } 87 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"); 103 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"); 116 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); 146 } 147 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"); 163 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"); 176 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); 206 } 207 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"); 223 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"); 236 237 SimpleTest.finish(); 238 }); 239 </script> 240 </body> 241 </html>