summaryrefslogtreecommitdiffstats
path: root/dom/bindings/test/test_bug1123516_maplikesetlike.html
diff options
context:
space:
mode:
Diffstat (limited to 'dom/bindings/test/test_bug1123516_maplikesetlike.html')
-rw-r--r--dom/bindings/test/test_bug1123516_maplikesetlike.html278
1 files changed, 278 insertions, 0 deletions
diff --git a/dom/bindings/test/test_bug1123516_maplikesetlike.html b/dom/bindings/test/test_bug1123516_maplikesetlike.html
new file mode 100644
index 0000000000..bc5048eb05
--- /dev/null
+++ b/dom/bindings/test/test_bug1123516_maplikesetlike.html
@@ -0,0 +1,278 @@
+<!-- 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 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">
+ /* global TestInterfaceMaplike, TestInterfaceSetlike, TestInterfaceMaplikeObject, TestInterfaceMaplikeJSObject*/
+ SimpleTest.waitForExplicitFinish();
+ SpecialPowers.pushPrefEnv({set: [["dom.expose_test_interfaces", true]]}, function() {
+ var base_properties = [["has", "function", 1],
+ ["entries", "function", 0],
+ ["keys", "function", 0],
+ ["values", "function", 0],
+ ["forEach", "function", 1],
+ ["size", "number"]];
+ var maplike_properties = base_properties.concat([["set", "function", 2]]);
+ var rw_properties = [["clear", "function", 0],
+ ["delete", "function", 1]];
+ var setlike_rw_properties = base_properties.concat(rw_properties).concat([["add", "function", 1]]);
+ var 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} should be 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");
+ var 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");
+ 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");
+ var iterable = false;
+ for (let 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, "entries", "SimpleMap: @@iterator symbol has correct name");
+ is(m[Symbol.iterator], m.entries, 'SimpleMap: @@iterator is an alias for "entries"');
+ ok(iterable, "SimpleMap: @@iterator symbol resolved correctly");
+ for (let k of m.keys()) {
+ is(k, "test", "SimpleMap: first keys element should be 'test'");
+ }
+ for (let v of m.values()) {
+ is(v, 1, "SimpleMap: first values elements should be 1");
+ }
+ for (let 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");
+ 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 (let 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, "values", "SimpleSet: @@iterator symbol has correct name");
+ is(m[Symbol.iterator], m.values, 'SimpleSet: @@iterator is an alias for "values"');
+ ok(iterable, "SimpleSet: @@iterator symbol resolved correctly");
+ for (let k of m.keys()) {
+ is(k, "test", "SimpleSet: first keys element should be 'test'");
+ }
+ for (let v of m.values()) {
+ is(v, "test", "SimpleSet: first values elements should be 'test'");
+ }
+ for (let 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");
+ // It's fine to let getInternal to return 0 if the key doesn't exist
+ // because this API can only be used internally in C++ and we'd throw
+ // an error if the key doesn't exist.
+ SimpleTest.doesThrow(() => m.getInternal("test"), 0, "MapConvenience: maplike getInternal should throw if the key doesn't exist");
+ 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");
+ is(m.getInternal("test"), 1, "MapConvenience: maplike getInternal should return value entered");
+ 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.getInternal("test2"), 2, "MapConvenience: maplike getInternal 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");
+ SimpleTest.doesThrow(() => m.getInternal("test"), "ReadOnlyMapConvenience: maplike getInternal should throw when the key doesn't exist");
+ m.setInternal("test");
+ is(m.size, 1, "size should be 1");
+ ok(m.hasInternal("test"), "ReadOnlyMapConvenience: maplike hasInternal should return true");
+ ok(m.getInternal("test") instanceof TestInterfaceMaplike, "ReadOnlyMapConvenience: maplike getInternal should return the object");
+ m.setInternal("test2");
+ is(m.size, 2, "size should be 2");
+ ok(m.hasInternal("test2"), "ReadOnlyMapConvenience: maplike hasInternal should return true");
+ ok(m.getInternal("test2") instanceof TestInterfaceMaplike, "ReadOnlyMapConvenience: maplike getInternal should return the object");
+ 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");
+
+ // Map convenience function test using JavaScript objects
+ info("Testing Map convenience function test using javascript objects");
+ m = new TestInterfaceMaplikeJSObject();
+ ok(m, "JSObjectMapConvenience: got a TestInterfaceMaplikeJSObject object");
+ is(m.size, 0, "JSObjectMapConvenience: size should be zero");
+ is(m.set, undefined, "JSObjectMapConvenience: readonly map, should be no set function");
+ is(m.clear, undefined, "JSObjectMapConvenience: readonly map, should be no clear function");
+ is(m.delete, undefined, "JSObjectMapConvenience: readonly map, should be no delete function");
+ ok(!m.hasInternal("test"), "JSObjectMapConvenience: maplike hasInternal should return false");
+ SimpleTest.doesThrow(() => m.getInternal("test"), "JSObjectMapConvenience: maplike getInternal should throw when the key doesn't exist");
+ let testObject = {"Hey1": 1};
+ m.setInternal("test", testObject);
+ is(m.size, 1, "size should be 1");
+ ok(m.hasInternal("test"), "JSObjectMapConvenience: maplike hasInternal should return true");
+ let addedObject = m.getInternal("test");
+ is(addedObject, testObject, "JSObjectMapConvenience: maplike getInternal should return the object");
+ testObject = {"Hey2": 2};
+ m.setInternal("test2", testObject);
+ is(m.size, 2, "size should be 2");
+ ok(m.hasInternal("test2"), "JSObjectMapConvenience: maplike hasInternal should return true");
+ addedObject = m.getInternal("test2");
+ is(addedObject, testObject, "JSObjectMapConvenience: maplike getInternal should return the object");
+ is(m.deleteInternal("test2"), true, "JSObjectMapConvenience: maplike deleteInternal should return true");
+ is(m.size, 1, "JSObjectMapConvenience: size should be 1");
+ m.clearInternal();
+ is(m.size, 0, "JSObjectMapConvenience: size should be 0 after clearInternal");
+ // JS implemented map creation convenience function test
+
+ // 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>