diff options
Diffstat (limited to 'dom/bindings/test/test_iterable.html')
-rw-r--r-- | dom/bindings/test/test_iterable.html | 241 |
1 files changed, 241 insertions, 0 deletions
diff --git a/dom/bindings/test/test_iterable.html b/dom/bindings/test/test_iterable.html new file mode 100644 index 000000000..8ce818e76 --- /dev/null +++ b/dom/bindings/test/test_iterable.html @@ -0,0 +1,241 @@ +<!-- 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> |