2015-10-15 20:06:44 +03:00
|
|
|
<!-- 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],
|
2016-02-18 06:58:04 +03:00
|
|
|
["values", "function", 0],
|
|
|
|
["forEach", "function", 1]]
|
2015-10-15 20:06:44 +03:00
|
|
|
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);
|
2016-02-18 06:57:57 +03:00
|
|
|
is(itr[Symbol.iterator], Array.prototype[Symbol.iterator],
|
|
|
|
"IterableSingle: Should be using %ArrayIterator% for @@iterator");
|
2016-02-18 06:58:00 +03:00
|
|
|
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'");
|
2016-02-18 06:58:04 +03:00
|
|
|
is(itr.forEach, Array.prototype.forEach,
|
|
|
|
"IterableSingle: Should be using %ArrayIterator% for 'forEach'");
|
2015-11-19 02:26:07 +03:00
|
|
|
var keys = [...itr.keys()];
|
|
|
|
var values = [...itr.values()];
|
|
|
|
var entries = [...itr.entries()];
|
2015-10-15 20:06:44 +03:00
|
|
|
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);
|
2015-11-19 02:26:07 +03:00
|
|
|
is(key.value, keys[i],
|
|
|
|
"IterableSingle: Key iterator value should match destructuring " + i);
|
2015-10-15 20:06:44 +03:00
|
|
|
is(value.value, key.value, "IterableSingle: Value iterator value should be " + key.value);
|
2015-11-19 02:26:07 +03:00
|
|
|
is(value.value, values[i],
|
|
|
|
"IterableSingle: Value iterator value should match destructuring " + i);
|
2015-10-15 20:06:44 +03:00
|
|
|
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);
|
2015-11-19 02:26:07 +03:00
|
|
|
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);
|
2015-10-15 20:06:44 +03:00
|
|
|
}
|
2016-02-18 06:58:04 +03:00
|
|
|
|
|
|
|
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");
|
|
|
|
|
2015-10-15 20:06:44 +03:00
|
|
|
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)),
|
2016-02-18 06:58:00 +03:00
|
|
|
"[object Array Iterator]",
|
2015-10-15 20:06:44 +03:00
|
|
|
"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);
|
2016-02-18 06:58:02 +03:00
|
|
|
is(itr.entries, itr[Symbol.iterator],
|
|
|
|
"IterableDouble: Should be using @@iterator for 'entries'");
|
2015-10-15 20:06:44 +03:00
|
|
|
var elements = [["a", "b"], ["c", "d"], ["e", "f"]]
|
2015-11-19 02:26:07 +03:00
|
|
|
var keys = [...itr.keys()];
|
|
|
|
var values = [...itr.values()];
|
|
|
|
var entries = [...itr.entries()];
|
2015-10-15 20:06:44 +03:00
|
|
|
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]);
|
2015-11-19 02:26:07 +03:00
|
|
|
is(key.value, keys[i],
|
|
|
|
"IterableDouble: Key iterator value should match destructuring " + i);
|
2015-10-15 20:06:44 +03:00
|
|
|
is(value.value, elements[i][1], "IterableDouble: Value iterator value should be " + elements[i][1]);
|
2015-11-19 02:26:07 +03:00
|
|
|
is(value.value, values[i],
|
|
|
|
"IterableDouble: Value iterator value should match destructuring " + i);
|
2015-10-15 20:06:44 +03:00
|
|
|
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]);
|
2015-11-19 02:26:07 +03:00
|
|
|
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);
|
2015-10-15 20:06:44 +03:00
|
|
|
}
|
2016-02-18 06:58:04 +03:00
|
|
|
|
|
|
|
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");
|
|
|
|
|
2015-10-15 20:06:44 +03:00
|
|
|
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");
|
|
|
|
|
2016-07-27 19:46:02 +03:00
|
|
|
// 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");
|
|
|
|
|
2015-10-15 20:06:44 +03:00
|
|
|
SimpleTest.finish();
|
|
|
|
});
|
|
|
|
</script>
|
|
|
|
</body>
|
|
|
|
</html>
|