зеркало из https://github.com/mozilla/gecko-dev.git
270 строки
15 KiB
HTML
270 строки
15 KiB
HTML
<!-- Any copyright is dedicated to the Public Domain.
|
|
- http://creativecommons.org/publicdomain/zero/1.0/ -->
|
|
<!DOCTYPE HTML>
|
|
<html>
|
|
<head>
|
|
<title>Test Maplike 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 = [["has", "function", 1],
|
|
["entries", "function", 0],
|
|
["keys", "function", 0],
|
|
["values", "function", 0],
|
|
["forEach", "function", 1],
|
|
["size", "number"]];
|
|
maplike_properties = base_properties.concat([["set", "function", 2]]);
|
|
setlike_properties = base_properties;
|
|
rw_properties = [["clear", "function", 0],
|
|
["delete", "function", 1]];
|
|
setlike_rw_properties = base_properties.concat(rw_properties).concat([["add", "function", 1]]);
|
|
maplike_rw_properties = maplike_properties.concat(rw_properties).concat([["get", "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 not enumerable`);
|
|
break;
|
|
}
|
|
owner = Object.getPrototypeOf(owner);
|
|
}
|
|
}
|
|
}
|
|
|
|
var m;
|
|
var testSet;
|
|
var testIndex;
|
|
// Simple map creation and functionality test
|
|
info("SimpleMap: Testing simple map creation and functionality");
|
|
m = new TestInterfaceMaplike();
|
|
ok(m, "SimpleMap: got a TestInterfaceMaplike object");
|
|
testExistence("SimpleMap: ", m, maplike_rw_properties);
|
|
is(m.size, 0, "SimpleMap: size should be zero");
|
|
ok(!m.has("test"), "SimpleMap: maplike has should return false");
|
|
is(m.get("test"), undefined, "SimpleMap: maplike get should return undefined on bogus lookup");
|
|
m1 = m.set("test", 1);
|
|
is(m, m1, "SimpleMap: return from set should be map object");
|
|
is(m.size, 1, "SimpleMap: size should be 1");
|
|
ok(m.has("test"), "SimpleMap: maplike has should return true");
|
|
is(m.get("test"), 1, "SimpleMap: maplike get should return value entered");
|
|
m2 = m.set("test2", 2);
|
|
is(m.size, 2, "SimpleMap: size should be 2");
|
|
testSet = [["test", 1], ["test2", 2]];
|
|
testIndex = 0;
|
|
m.forEach(function(v, k, o) {
|
|
"use strict";
|
|
is(o, m, "SimpleMap: foreach obj is correct");
|
|
is(k, testSet[testIndex][0], "SimpleMap: foreach map key: " + k + " = " + testSet[testIndex][0]);
|
|
is(v, testSet[testIndex][1], "SimpleMap: foreach map value: " + v + " = " + testSet[testIndex][1]);
|
|
testIndex += 1;
|
|
});
|
|
is(testIndex, 2, "SimpleMap: foreach ran correct number of times");
|
|
ok(m.has("test2"), "SimpleMap: maplike has should return true");
|
|
is(m.get("test2"), 2, "SimpleMap: maplike get should return value entered");
|
|
is(m.delete("test2"), true, "SimpleMap: maplike deletion should return boolean");
|
|
is(m.size, 1, "SimpleMap: size should be 1");
|
|
iterable = false;
|
|
for (var e of m) {
|
|
iterable = true;
|
|
is(e[0], "test", "SimpleMap: iterable first array element should be key");
|
|
is(e[1], 1, "SimpleMap: iterable second array element should be value");
|
|
}
|
|
is(m[Symbol.iterator].length, 0, "SimpleMap: @@iterator symbol is correct length");
|
|
is(m[Symbol.iterator].name, "[Symbol.iterator]", "SimpleMap: @@iterator symbol has correct name");
|
|
ok(iterable, "SimpleMap: @@iterator symbol resolved correctly");
|
|
for (var k of m.keys()) {
|
|
is(k, "test", "SimpleMap: first keys element should be 'test'");
|
|
}
|
|
for (var v of m.values()) {
|
|
is(v, 1, "SimpleMap: first values elements should be 1");
|
|
}
|
|
for (var e of m.entries()) {
|
|
is(e[0], "test", "SimpleMap: entries first array element should be 'test'");
|
|
is(e[1], 1, "SimpleMap: entries second array element should be 1");
|
|
}
|
|
m.clear();
|
|
is(m.size, 0, "SimpleMap: size should be 0 after clear");
|
|
|
|
// Simple set creation and functionality test
|
|
info("SimpleSet: Testing simple set creation and functionality");
|
|
m = new TestInterfaceSetlike();
|
|
ok(m, "SimpleSet: got a TestInterfaceSetlike object");
|
|
testExistence("SimpleSet: ", m, setlike_rw_properties);
|
|
is(m.size, 0, "SimpleSet: size should be zero");
|
|
ok(!m.has("test"), "SimpleSet: maplike has should return false");
|
|
m1 = m.add("test");
|
|
is(m, m1, "SimpleSet: return from set should be map object");
|
|
is(m.size, 1, "SimpleSet: size should be 1");
|
|
ok(m.has("test"), "SimpleSet: maplike has should return true");
|
|
m2 = m.add("test2");
|
|
is(m.size, 2, "SimpleSet: size should be 2");
|
|
testSet = ["test", "test2"];
|
|
testIndex = 0;
|
|
m.forEach(function(v, k, o) {
|
|
"use strict";
|
|
is(o, m, "SimpleSet: foreach obj is correct");
|
|
is(k, testSet[testIndex], "SimpleSet: foreach set key: " + k + " = " + testSet[testIndex]);
|
|
testIndex += 1;
|
|
});
|
|
is(testIndex, 2, "SimpleSet: foreach ran correct number of times");
|
|
ok(m.has("test2"), "SimpleSet: maplike has should return true");
|
|
is(m.delete("test2"), true, "SimpleSet: maplike deletion should return true");
|
|
is(m.size, 1, "SimpleSet: size should be 1");
|
|
iterable = false;
|
|
for (var e of m) {
|
|
iterable = true;
|
|
is(e, "test", "SimpleSet: iterable first array element should be key");
|
|
}
|
|
is(m[Symbol.iterator].length, 0, "SimpleSet: @@iterator symbol is correct length");
|
|
is(m[Symbol.iterator].name, "[Symbol.iterator]", "SimpleSet: @@iterator symbol has correct name");
|
|
ok(iterable, "SimpleSet: @@iterator symbol resolved correctly");
|
|
for (var k of m.keys()) {
|
|
is(k, "test", "SimpleSet: first keys element should be 'test'");
|
|
}
|
|
for (var v of m.values()) {
|
|
is(v, "test", "SimpleSet: first values elements should be 'test'");
|
|
}
|
|
for (var e of m.entries()) {
|
|
is(e[0], "test", "SimpleSet: Entries first array element should be 'test'");
|
|
is(e[1], "test", "SimpleSet: Entries second array element should be 'test'");
|
|
}
|
|
m.clear();
|
|
is(m.size, 0, "SimpleSet: size should be 0 after clear");
|
|
|
|
// Map convenience function test
|
|
info("Testing map convenience functions");
|
|
m = new TestInterfaceMaplike();
|
|
ok(m, "MapConvenience: got a TestInterfaceMaplike object");
|
|
is(m.size, 0, "MapConvenience: size should be zero");
|
|
ok(!m.hasInternal("test"), "MapConvenience: maplike hasInternal should return false");
|
|
m.setInternal("test", 1);
|
|
is(m.size, 1, "MapConvenience: size should be 1");
|
|
ok(m.hasInternal("test"), "MapConvenience: maplike hasInternal should return true");
|
|
is(m.get("test"), 1, "MapConvenience: maplike get should return value entered");
|
|
m2 = m.setInternal("test2", 2);
|
|
is(m.size, 2, "size should be 2");
|
|
ok(m.hasInternal("test2"), "MapConvenience: maplike hasInternal should return true");
|
|
is(m.get("test2"), 2, "MapConvenience: maplike get should return value entered");
|
|
is(m.deleteInternal("test2"), true, "MapConvenience: maplike deleteInternal should return true");
|
|
is(m.size, 1, "MapConvenience: size should be 1");
|
|
m.clearInternal();
|
|
is(m.size, 0, "MapConvenience: size should be 0 after clearInternal");
|
|
|
|
// Map convenience function test using objects and readonly
|
|
|
|
info("Testing Map convenience function test using objects and readonly");
|
|
m = new TestInterfaceMaplikeObject();
|
|
ok(m, "ReadOnlyMapConvenience: got a TestInterfaceMaplikeObject object");
|
|
is(m.size, 0, "ReadOnlyMapConvenience: size should be zero");
|
|
is(m["set"], undefined, "ReadOnlyMapConvenience: readonly map, should be no set function");
|
|
is(m["clear"], undefined, "ReadOnlyMapConvenience: readonly map, should be no clear function");
|
|
is(m["delete"], undefined, "ReadOnlyMapConvenience: readonly map, should be no delete function");
|
|
ok(!m.hasInternal("test"), "ReadOnlyMapConvenience: maplike hasInternal should return false");
|
|
m.setInternal("test");
|
|
is(m.size, 1, "size should be 1");
|
|
ok(m.hasInternal("test"), "ReadOnlyMapConvenience: maplike hasInternal should return true");
|
|
m2 = m.setInternal("test2");
|
|
is(m.size, 2, "size should be 2");
|
|
ok(m.hasInternal("test2"), "ReadOnlyMapConvenience: maplike hasInternal should return true");
|
|
is(m.deleteInternal("test2"), true, "ReadOnlyMapConvenience: maplike deleteInternal should return true");
|
|
is(m.size, 1, "ReadOnlyMapConvenience: size should be 1");
|
|
m.clearInternal();
|
|
is(m.size, 0, "ReadOnlyMapConvenience: size should be 0 after clearInternal");
|
|
|
|
// JS implemented map creation convenience function test
|
|
|
|
info("JSMapConvenience: Testing JS implemented map creation convenience functions");
|
|
m = new TestInterfaceJSMaplike();
|
|
ok(m, "JSMapConvenience: got a TestInterfaceJSMaplike object");
|
|
is(m.size, 0, "JSMapConvenience: size should be zero");
|
|
ok(!m.has("test"), "JSMapConvenience: maplike has should return false");
|
|
m.setInternal("test", 1);
|
|
is(m.size, 1, "JSMapConvenience: size should be 1");
|
|
ok(m.has("test"), "JSMapConvenience: maplike has should return true");
|
|
is(m.get("test"), 1, "JSMapConvenience: maplike get should return value entered");
|
|
m2 = m.setInternal("test2", 2);
|
|
is(m.size, 2, "JSMapConvenience: size should be 2");
|
|
ok(m.has("test2"), "JSMapConvenience: maplike has should return true");
|
|
is(m.get("test2"), 2, "JSMapConvenience: maplike get should return value entered");
|
|
is(m.deleteInternal("test2"), true, "JSMapConvenience: maplike deleteInternal should return true");
|
|
is(m.size, 1, "JSMapConvenience: size should be 1");
|
|
for (var k of m.keys()) {
|
|
is(k, "test", "JSMapConvenience: first keys element should be 'test'");
|
|
}
|
|
for (var v of m.values()) {
|
|
is(v, 1, "JSMapConvenience: first values elements should be 1");
|
|
}
|
|
for (var e of m.entries()) {
|
|
is(e[0], "test", "JSMapConvenience: entries first array element should be 'test'");
|
|
is(e[1], 1, "JSMapConvenience: entries second array element should be 1");
|
|
}
|
|
m.clearInternal();
|
|
is(m.size, 0, "JSMapConvenience: size should be 0 after clearInternal");
|
|
|
|
// Test this override for forEach
|
|
info("ForEachThisOverride: Testing this override for forEach");
|
|
m = new TestInterfaceMaplike();
|
|
m.set("test", 1);
|
|
m.forEach(function(v, k, o) {
|
|
"use strict";
|
|
is(o, m, "ForEachThisOverride: foreach obj is correct");
|
|
is(this, 5, "ForEachThisOverride: 'this' value should be correct");
|
|
}, 5);
|
|
|
|
// Test defaulting arguments on maplike to undefined
|
|
info("MapArgsDefault: Testing maplike defaulting arguments to undefined");
|
|
m = new TestInterfaceMaplike();
|
|
m.set();
|
|
is(m.size, 1, "MapArgsDefault: should have 1 entry");
|
|
m.forEach(function(v, k) {
|
|
"use strict";
|
|
is(typeof k, "string", "MapArgsDefault: key is a string");
|
|
is(k, "undefined", "MapArgsDefault: key is the string undefined");
|
|
is(v, 0, "MapArgsDefault: value is 0");
|
|
});
|
|
is(m.get(), 0, "MapArgsDefault: no argument to get() returns correct value");
|
|
m.delete();
|
|
is(m.size, 0, "MapArgsDefault: should have 0 entries");
|
|
|
|
// Test defaulting arguments on setlike to undefined
|
|
info("SetArgsDefault: Testing setlike defaulting arguments to undefined");
|
|
m = new TestInterfaceSetlike();
|
|
m.add();
|
|
is(m.size, 1, "SetArgsDefault: should have 1 entry");
|
|
m.forEach(function(v, k) {
|
|
"use strict";
|
|
is(typeof k, "string", "SetArgsDefault: key is a string");
|
|
is(k, "undefined", "SetArgsDefault: key is the string undefined");
|
|
});
|
|
m.delete();
|
|
is(m.size, 0, "SetArgsDefault: should have 0 entries");
|
|
|
|
SimpleTest.finish();
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|