1 <!-- Any copyright is dedicated to the Public Domain.
2 - http://creativecommons.org/publicdomain/zero/1.0/ -->
6 <title>Test Maplike Interface
</title>
7 <script src=
"/tests/SimpleTest/SimpleTest.js"></script>
8 <link rel=
"stylesheet" type=
"text/css" href=
"/tests/SimpleTest/test.css" />
11 <script class=
"testbody" type=
"application/javascript">
12 /* global TestInterfaceMaplike, TestInterfaceSetlike, TestInterfaceMaplikeObject, TestInterfaceMaplikeJSObject*/
13 SimpleTest.waitForExplicitFinish();
14 SpecialPowers.pushPrefEnv({set: [[
"dom.expose_test_interfaces", true]]}, function() {
15 var base_properties = [[
"has",
"function",
1],
16 [
"entries",
"function",
0],
17 [
"keys",
"function",
0],
18 [
"values",
"function",
0],
19 [
"forEach",
"function",
1],
21 var maplike_properties = base_properties.concat([[
"set",
"function",
2]]);
22 var rw_properties = [[
"clear",
"function",
0],
23 [
"delete",
"function",
1]];
24 var setlike_rw_properties = base_properties.concat(rw_properties).concat([[
"add",
"function",
1]]);
25 var maplike_rw_properties = maplike_properties.concat(rw_properties).concat([[
"get",
"function",
1]]);
26 var testExistence = function testExistence(prefix, obj, properties) {
27 for (var [name, type, args] of properties) {
28 // Properties are somewhere up the proto chain, hasOwnProperty won't work
29 isnot(obj[name], undefined,
30 `${prefix} object has property ${name}`);
32 is(typeof obj[name], type,
33 `${prefix} object property ${name} is a ${type}`);
34 // Check function length
35 if (type ==
"function") {
36 is(obj[name].length, args,
37 `${prefix} object property ${name} is length ${args}`);
38 is(obj[name].name, name,
39 `${prefix} object method name is ${name}`);
42 // Find where property is on proto chain, check for enumerablility there.
45 var propDesc = Object.getOwnPropertyDescriptor(owner, name);
47 ok(propDesc.enumerable,
48 `${prefix} object property ${name} should be enumerable`);
51 owner = Object.getPrototypeOf(owner);
60 // Simple map creation and functionality test
61 info(
"SimpleMap: Testing simple map creation and functionality");
62 m = new TestInterfaceMaplike();
63 ok(m,
"SimpleMap: got a TestInterfaceMaplike object");
64 testExistence(
"SimpleMap: ", m, maplike_rw_properties);
65 is(m.size,
0,
"SimpleMap: size should be zero");
66 ok(!m.has(
"test"),
"SimpleMap: maplike has should return false");
67 is(m.get(
"test"), undefined,
"SimpleMap: maplike get should return undefined on bogus lookup");
68 var m1 = m.set(
"test",
1);
69 is(m, m1,
"SimpleMap: return from set should be map object");
70 is(m.size,
1,
"SimpleMap: size should be 1");
71 ok(m.has(
"test"),
"SimpleMap: maplike has should return true");
72 is(m.get(
"test"),
1,
"SimpleMap: maplike get should return value entered");
74 is(m.size,
2,
"SimpleMap: size should be 2");
75 testSet = [[
"test",
1], [
"test2",
2]];
77 m.forEach(function(v, k, o) {
79 is(o, m,
"SimpleMap: foreach obj is correct");
80 is(k, testSet[testIndex][
0],
"SimpleMap: foreach map key: " + k +
" = " + testSet[testIndex][
0]);
81 is(v, testSet[testIndex][
1],
"SimpleMap: foreach map value: " + v +
" = " + testSet[testIndex][
1]);
84 is(testIndex,
2,
"SimpleMap: foreach ran correct number of times");
85 ok(m.has(
"test2"),
"SimpleMap: maplike has should return true");
86 is(m.get(
"test2"),
2,
"SimpleMap: maplike get should return value entered");
87 is(m.delete(
"test2"), true,
"SimpleMap: maplike deletion should return boolean");
88 is(m.size,
1,
"SimpleMap: size should be 1");
92 is(e[
0],
"test",
"SimpleMap: iterable first array element should be key");
93 is(e[
1],
1,
"SimpleMap: iterable second array element should be value");
95 is(m[Symbol.iterator].length,
0,
"SimpleMap: @@iterator symbol is correct length");
96 is(m[Symbol.iterator].name,
"entries",
"SimpleMap: @@iterator symbol has correct name");
97 is(m[Symbol.iterator], m.entries, 'SimpleMap: @@iterator is an alias for
"entries"');
98 ok(iterable,
"SimpleMap: @@iterator symbol resolved correctly");
99 for (let k of m.keys()) {
100 is(k,
"test",
"SimpleMap: first keys element should be 'test'");
102 for (let v of m.values()) {
103 is(v,
1,
"SimpleMap: first values elements should be 1");
105 for (let e of m.entries()) {
106 is(e[
0],
"test",
"SimpleMap: entries first array element should be 'test'");
107 is(e[
1],
1,
"SimpleMap: entries second array element should be 1");
110 is(m.size,
0,
"SimpleMap: size should be 0 after clear");
112 // Simple set creation and functionality test
113 info(
"SimpleSet: Testing simple set creation and functionality");
114 m = new TestInterfaceSetlike();
115 ok(m,
"SimpleSet: got a TestInterfaceSetlike object");
116 testExistence(
"SimpleSet: ", m, setlike_rw_properties);
117 is(m.size,
0,
"SimpleSet: size should be zero");
118 ok(!m.has(
"test"),
"SimpleSet: maplike has should return false");
120 is(m, m1,
"SimpleSet: return from set should be map object");
121 is(m.size,
1,
"SimpleSet: size should be 1");
122 ok(m.has(
"test"),
"SimpleSet: maplike has should return true");
124 is(m.size,
2,
"SimpleSet: size should be 2");
125 testSet = [
"test",
"test2"];
127 m.forEach(function(v, k, o) {
129 is(o, m,
"SimpleSet: foreach obj is correct");
130 is(k, testSet[testIndex],
"SimpleSet: foreach set key: " + k +
" = " + testSet[testIndex]);
133 is(testIndex,
2,
"SimpleSet: foreach ran correct number of times");
134 ok(m.has(
"test2"),
"SimpleSet: maplike has should return true");
135 is(m.delete(
"test2"), true,
"SimpleSet: maplike deletion should return true");
136 is(m.size,
1,
"SimpleSet: size should be 1");
140 is(e,
"test",
"SimpleSet: iterable first array element should be key");
142 is(m[Symbol.iterator].length,
0,
"SimpleSet: @@iterator symbol is correct length");
143 is(m[Symbol.iterator].name,
"values",
"SimpleSet: @@iterator symbol has correct name");
144 is(m[Symbol.iterator], m.values, 'SimpleSet: @@iterator is an alias for
"values"');
145 ok(iterable,
"SimpleSet: @@iterator symbol resolved correctly");
146 for (let k of m.keys()) {
147 is(k,
"test",
"SimpleSet: first keys element should be 'test'");
149 for (let v of m.values()) {
150 is(v,
"test",
"SimpleSet: first values elements should be 'test'");
152 for (let e of m.entries()) {
153 is(e[
0],
"test",
"SimpleSet: Entries first array element should be 'test'");
154 is(e[
1],
"test",
"SimpleSet: Entries second array element should be 'test'");
157 is(m.size,
0,
"SimpleSet: size should be 0 after clear");
159 // Map convenience function test
160 info(
"Testing map convenience functions");
161 m = new TestInterfaceMaplike();
162 ok(m,
"MapConvenience: got a TestInterfaceMaplike object");
163 is(m.size,
0,
"MapConvenience: size should be zero");
164 ok(!m.hasInternal(
"test"),
"MapConvenience: maplike hasInternal should return false");
165 // It's fine to let getInternal to return
0 if the key doesn't exist
166 // because this API can only be used internally in C++ and we'd throw
167 // an error if the key doesn't exist.
168 SimpleTest.doesThrow(() =
> m.getInternal(
"test"),
0,
"MapConvenience: maplike getInternal should throw if the key doesn't exist");
169 m.setInternal(
"test",
1);
170 is(m.size,
1,
"MapConvenience: size should be 1");
171 ok(m.hasInternal(
"test"),
"MapConvenience: maplike hasInternal should return true");
172 is(m.get(
"test"),
1,
"MapConvenience: maplike get should return value entered");
173 is(m.getInternal(
"test"),
1,
"MapConvenience: maplike getInternal should return value entered");
174 m.setInternal(
"test2",
2);
175 is(m.size,
2,
"size should be 2");
176 ok(m.hasInternal(
"test2"),
"MapConvenience: maplike hasInternal should return true");
177 is(m.get(
"test2"),
2,
"MapConvenience: maplike get should return value entered");
178 is(m.getInternal(
"test2"),
2,
"MapConvenience: maplike getInternal should return value entered");
179 is(m.deleteInternal(
"test2"), true,
"MapConvenience: maplike deleteInternal should return true");
180 is(m.size,
1,
"MapConvenience: size should be 1");
182 is(m.size,
0,
"MapConvenience: size should be 0 after clearInternal");
184 // Map convenience function test using objects and readonly
186 info(
"Testing Map convenience function test using objects and readonly");
187 m = new TestInterfaceMaplikeObject();
188 ok(m,
"ReadOnlyMapConvenience: got a TestInterfaceMaplikeObject object");
189 is(m.size,
0,
"ReadOnlyMapConvenience: size should be zero");
190 is(m.set, undefined,
"ReadOnlyMapConvenience: readonly map, should be no set function");
191 is(m.clear, undefined,
"ReadOnlyMapConvenience: readonly map, should be no clear function");
192 is(m.delete, undefined,
"ReadOnlyMapConvenience: readonly map, should be no delete function");
193 ok(!m.hasInternal(
"test"),
"ReadOnlyMapConvenience: maplike hasInternal should return false");
194 SimpleTest.doesThrow(() =
> m.getInternal(
"test"),
"ReadOnlyMapConvenience: maplike getInternal should throw when the key doesn't exist");
195 m.setInternal(
"test");
196 is(m.size,
1,
"size should be 1");
197 ok(m.hasInternal(
"test"),
"ReadOnlyMapConvenience: maplike hasInternal should return true");
198 ok(m.getInternal(
"test") instanceof TestInterfaceMaplike,
"ReadOnlyMapConvenience: maplike getInternal should return the object");
199 m.setInternal(
"test2");
200 is(m.size,
2,
"size should be 2");
201 ok(m.hasInternal(
"test2"),
"ReadOnlyMapConvenience: maplike hasInternal should return true");
202 ok(m.getInternal(
"test2") instanceof TestInterfaceMaplike,
"ReadOnlyMapConvenience: maplike getInternal should return the object");
203 is(m.deleteInternal(
"test2"), true,
"ReadOnlyMapConvenience: maplike deleteInternal should return true");
204 is(m.size,
1,
"ReadOnlyMapConvenience: size should be 1");
206 is(m.size,
0,
"ReadOnlyMapConvenience: size should be 0 after clearInternal");
208 // Map convenience function test using JavaScript objects
209 info(
"Testing Map convenience function test using javascript objects");
210 m = new TestInterfaceMaplikeJSObject();
211 ok(m,
"JSObjectMapConvenience: got a TestInterfaceMaplikeJSObject object");
212 is(m.size,
0,
"JSObjectMapConvenience: size should be zero");
213 is(m.set, undefined,
"JSObjectMapConvenience: readonly map, should be no set function");
214 is(m.clear, undefined,
"JSObjectMapConvenience: readonly map, should be no clear function");
215 is(m.delete, undefined,
"JSObjectMapConvenience: readonly map, should be no delete function");
216 ok(!m.hasInternal(
"test"),
"JSObjectMapConvenience: maplike hasInternal should return false");
217 SimpleTest.doesThrow(() =
> m.getInternal(
"test"),
"JSObjectMapConvenience: maplike getInternal should throw when the key doesn't exist");
218 let testObject = {
"Hey1":
1};
219 m.setInternal(
"test", testObject);
220 is(m.size,
1,
"size should be 1");
221 ok(m.hasInternal(
"test"),
"JSObjectMapConvenience: maplike hasInternal should return true");
222 let addedObject = m.getInternal(
"test");
223 is(addedObject, testObject,
"JSObjectMapConvenience: maplike getInternal should return the object");
224 testObject = {
"Hey2":
2};
225 m.setInternal(
"test2", testObject);
226 is(m.size,
2,
"size should be 2");
227 ok(m.hasInternal(
"test2"),
"JSObjectMapConvenience: maplike hasInternal should return true");
228 addedObject = m.getInternal(
"test2");
229 is(addedObject, testObject,
"JSObjectMapConvenience: maplike getInternal should return the object");
230 is(m.deleteInternal(
"test2"), true,
"JSObjectMapConvenience: maplike deleteInternal should return true");
231 is(m.size,
1,
"JSObjectMapConvenience: size should be 1");
233 is(m.size,
0,
"JSObjectMapConvenience: size should be 0 after clearInternal");
234 // JS implemented map creation convenience function test
236 // Test this override for forEach
237 info(
"ForEachThisOverride: Testing this override for forEach");
238 m = new TestInterfaceMaplike();
240 m.forEach(function(v, k, o) {
242 is(o, m,
"ForEachThisOverride: foreach obj is correct");
243 is(this,
5,
"ForEachThisOverride: 'this' value should be correct");
246 // Test defaulting arguments on maplike to undefined
247 info(
"MapArgsDefault: Testing maplike defaulting arguments to undefined");
248 m = new TestInterfaceMaplike();
250 is(m.size,
1,
"MapArgsDefault: should have 1 entry");
251 m.forEach(function(v, k) {
253 is(typeof k,
"string",
"MapArgsDefault: key is a string");
254 is(k,
"undefined",
"MapArgsDefault: key is the string undefined");
255 is(v,
0,
"MapArgsDefault: value is 0");
257 is(m.get(),
0,
"MapArgsDefault: no argument to get() returns correct value");
259 is(m.size,
0,
"MapArgsDefault: should have 0 entries");
261 // Test defaulting arguments on setlike to undefined
262 info(
"SetArgsDefault: Testing setlike defaulting arguments to undefined");
263 m = new TestInterfaceSetlike();
265 is(m.size,
1,
"SetArgsDefault: should have 1 entry");
266 m.forEach(function(v, k) {
268 is(typeof k,
"string",
"SetArgsDefault: key is a string");
269 is(k,
"undefined",
"SetArgsDefault: key is the string undefined");
272 is(m.size,
0,
"SetArgsDefault: should have 0 entries");