<!-- Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ --> <!DOCTYPE HTML> <html> <head> <title>Test Iterable Interface</title> <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> </head> <body> <script class="testbody" type="application/javascript"> SimpleTest.waitForExplicitFinish(); SpecialPowers.pushPrefEnv({set: [['dom.expose_test_interfaces', true]]}, function() { base_properties = [["entries", "function", 0], ["keys", "function", 0], ["values", "function", 0], ["forEach", "function", 1]] var testExistence = function testExistence(prefix, obj, properties) { for (var [name, type, args] of properties) { // Properties are somewhere up the proto chain, hasOwnProperty won't work isnot(obj[name], undefined, `${prefix} object has property ${name}`); is(typeof obj[name], type, `${prefix} object property ${name} is a ${type}`); // Check function length if (type == "function") { is(obj[name].length, args, `${prefix} object property ${name} is length ${args}`); is(obj[name].name, name, `${prefix} object method name is ${name}`); } // Find where property is on proto chain, check for enumerablility there. var owner = obj; while (owner) { var propDesc = Object.getOwnPropertyDescriptor(owner, name); if (propDesc) { ok(propDesc.enumerable, `${prefix} object property ${name} is enumerable`); break; } owner = Object.getPrototypeOf(owner); } } } var itr; // Simple single type iterable creation and functionality test info("IterableSingle: Testing simple iterable creation and functionality"); itr = new TestInterfaceIterableSingle(); testExistence("IterableSingle: ", itr, base_properties); is(itr[Symbol.iterator], Array.prototype[Symbol.iterator], "IterableSingle: Should be using %ArrayIterator% for @@iterator"); is(itr.keys, Array.prototype.keys, "IterableSingle: Should be using %ArrayIterator% for 'keys'"); is(itr.entries, Array.prototype.entries, "IterableSingle: Should be using %ArrayIterator% for 'entries'"); is(itr.values, itr[Symbol.iterator], "IterableSingle: Should be using @@iterator for 'values'"); is(itr.forEach, Array.prototype.forEach, "IterableSingle: Should be using %ArrayIterator% for 'forEach'"); var keys = [...itr.keys()]; var values = [...itr.values()]; var entries = [...itr.entries()]; var key_itr = itr.keys(); var value_itr = itr.values(); var entries_itr = itr.entries(); for (var i = 0; i < 3; ++i) { var key = key_itr.next(); var value = value_itr.next(); var entry = entries_itr.next(); is(key.value, i, "IterableSingle: Key iterator value should be " + i); is(key.value, keys[i], "IterableSingle: Key iterator value should match destructuring " + i); is(value.value, key.value, "IterableSingle: Value iterator value should be " + key.value); is(value.value, values[i], "IterableSingle: Value iterator value should match destructuring " + i); is(entry.value[0], i, "IterableSingle: Entry iterator value 0 should be " + i); is(entry.value[1], i, "IterableSingle: Entry iterator value 1 should be " + i); is(entry.value[0], entries[i][0], "IterableSingle: Entry iterator value 0 should match destructuring " + i); is(entry.value[1], entries[i][1], "IterableSingle: Entry iterator value 1 should match destructuring " + i); } var callsToForEachCallback = 0; var thisArg = {}; itr.forEach(function(value, index, obj) { is(index, callsToForEachCallback, `IterableSingle: Should have the right index at ${callsToForEachCallback} calls to forEach callback`); is(value, values[index], `IterableSingle: Should have the right value at ${callsToForEachCallback} calls to forEach callback`); is(this, thisArg, "IterableSingle: Should have the right this value for forEach callback"); is(obj, itr, "IterableSingle: Should have the right third arg for forEach callback"); ++callsToForEachCallback; }, thisArg); is(callsToForEachCallback, 3, "IterableSingle: Should have right total number of calls to forEach callback"); var key = key_itr.next(); var value = value_itr.next(); var entry = entries_itr.next(); is(key.value, undefined, "IterableSingle: Key iterator value should be undefined"); is(key.done, true, "IterableSingle: Key iterator done should be true"); is(value.value, undefined, "IterableSingle: Value iterator value should be undefined"); is(value.done, true, "IterableSingle: Value iterator done should be true"); is(entry.value, undefined, "IterableDouble: Entry iterator value should be undefined"); is(entry.done, true, "IterableSingle: Entry iterator done should be true"); is(Object.prototype.toString.call(Object.getPrototypeOf(key_itr)), "[object Array Iterator]", "iterator prototype should have the right brand"); // Simple dual type iterable creation and functionality test info("IterableDouble: Testing simple iterable creation and functionality"); itr = new TestInterfaceIterableDouble(); testExistence("IterableDouble: ", itr, base_properties); is(itr.entries, itr[Symbol.iterator], "IterableDouble: Should be using @@iterator for 'entries'"); var elements = [["a", "b"], ["c", "d"], ["e", "f"]] var keys = [...itr.keys()]; var values = [...itr.values()]; var entries = [...itr.entries()]; var key_itr = itr.keys(); var value_itr = itr.values(); var entries_itr = itr.entries(); for (var i = 0; i < 3; ++i) { var key = key_itr.next(); var value = value_itr.next(); var entry = entries_itr.next(); is(key.value, elements[i][0], "IterableDouble: Key iterator value should be " + elements[i][0]); is(key.value, keys[i], "IterableDouble: Key iterator value should match destructuring " + i); is(value.value, elements[i][1], "IterableDouble: Value iterator value should be " + elements[i][1]); is(value.value, values[i], "IterableDouble: Value iterator value should match destructuring " + i); is(entry.value[0], elements[i][0], "IterableDouble: Entry iterator value 0 should be " + elements[i][0]); is(entry.value[1], elements[i][1], "IterableDouble: Entry iterator value 1 should be " + elements[i][1]); is(entry.value[0], entries[i][0], "IterableDouble: Entry iterator value 0 should match destructuring " + i); is(entry.value[1], entries[i][1], "IterableDouble: Entry iterator value 1 should match destructuring " + i); } callsToForEachCallback = 0; thisArg = {}; itr.forEach(function(value, key, obj) { is(key, keys[callsToForEachCallback], `IterableDouble: Should have the right key at ${callsToForEachCallback} calls to forEach callback`); is(value, values[callsToForEachCallback], `IterableDouble: Should have the right value at ${callsToForEachCallback} calls to forEach callback`); is(this, thisArg, "IterableDouble: Should have the right this value for forEach callback"); is(obj, itr, "IterableSingle: Should have the right third arg for forEach callback"); ++callsToForEachCallback; }, thisArg); is(callsToForEachCallback, 3, "IterableDouble: Should have right total number of calls to forEach callback"); var key = key_itr.next(); var value = value_itr.next(); var entry = entries_itr.next() is(key.value, undefined, "IterableDouble: Key iterator value should be undefined"); is(key.done, true, "IterableDouble: Key iterator done should be true"); is(value.value, undefined, "IterableDouble: Value iterator value should be undefined"); is(value.done, true, "IterableDouble: Value iterator done should be true"); is(entry.value, undefined, "IterableDouble: Entry iterator value should be undefined"); is(entry.done, true, "IterableDouble: Entry iterator done should be true"); is(Object.prototype.toString.call(Object.getPrototypeOf(key_itr)), "[object TestInterfaceIterableDoubleIteratorPrototype]", "iterator prototype should have the right brand"); // Simple dual type iterable creation and functionality test info("IterableDoubleUnion: Testing simple iterable creation and functionality"); itr = new TestInterfaceIterableDoubleUnion(); testExistence("IterableDoubleUnion: ", itr, base_properties); is(itr.entries, itr[Symbol.iterator], "IterableDoubleUnion: Should be using @@iterator for 'entries'"); var elements = [["long", 1], ["string", "a"]] var keys = [...itr.keys()]; var values = [...itr.values()]; var entries = [...itr.entries()]; var key_itr = itr.keys(); var value_itr = itr.values(); var entries_itr = itr.entries(); for (var i = 0; i < elements.length; ++i) { var key = key_itr.next(); var value = value_itr.next(); var entry = entries_itr.next(); is(key.value, elements[i][0], "IterableDoubleUnion: Key iterator value should be " + elements[i][0]); is(key.value, keys[i], "IterableDoubleUnion: Key iterator value should match destructuring " + i); is(value.value, elements[i][1], "IterableDoubleUnion: Value iterator value should be " + elements[i][1]); is(value.value, values[i], "IterableDoubleUnion: Value iterator value should match destructuring " + i); is(entry.value[0], elements[i][0], "IterableDoubleUnion: Entry iterator value 0 should be " + elements[i][0]); is(entry.value[1], elements[i][1], "IterableDoubleUnion: Entry iterator value 1 should be " + elements[i][1]); is(entry.value[0], entries[i][0], "IterableDoubleUnion: Entry iterator value 0 should match destructuring " + i); is(entry.value[1], entries[i][1], "IterableDoubleUnion: Entry iterator value 1 should match destructuring " + i); } callsToForEachCallback = 0; thisArg = {}; itr.forEach(function(value, key, obj) { is(key, keys[callsToForEachCallback], `IterableDoubleUnion: Should have the right key at ${callsToForEachCallback} calls to forEach callback`); is(value, values[callsToForEachCallback], `IterableDoubleUnion: Should have the right value at ${callsToForEachCallback} calls to forEach callback`); is(this, thisArg, "IterableDoubleUnion: Should have the right this value for forEach callback"); is(obj, itr, "IterableSingle: Should have the right third arg for forEach callback"); ++callsToForEachCallback; }, thisArg); is(callsToForEachCallback, 2, "IterableDoubleUnion: Should have right total number of calls to forEach callback"); var key = key_itr.next(); var value = value_itr.next(); var entry = entries_itr.next() is(key.value, undefined, "IterableDoubleUnion: Key iterator value should be undefined"); is(key.done, true, "IterableDoubleUnion: Key iterator done should be true"); is(value.value, undefined, "IterableDoubleUnion: Value iterator value should be undefined"); is(value.done, true, "IterableDoubleUnion: Value iterator done should be true"); is(entry.value, undefined, "IterableDoubleUnion: Entry iterator value should be undefined"); is(entry.done, true, "IterableDoubleUnion: Entry iterator done should be true"); is(Object.prototype.toString.call(Object.getPrototypeOf(key_itr)), "[object TestInterfaceIterableDoubleUnionIteratorPrototype]", "iterator prototype should have the right brand"); SimpleTest.finish(); }); </script> </body> </html>