Bug 1942639 - Propagate --filter argument from desktop_unittest.py to runreftest...
[gecko.git] / dom / bindings / test / test_bug1123516_maplikesetlike.html
blobbc5048eb05151edcf450de4361370775d0fee1ba
1 <!-- Any copyright is dedicated to the Public Domain.
2 - http://creativecommons.org/publicdomain/zero/1.0/ -->
3 <!DOCTYPE HTML>
4 <html>
5 <head>
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" />
9 </head>
10 <body>
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],
20 ["size", "number"]];
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.
43 var owner = obj;
44 while (owner) {
45 var propDesc = Object.getOwnPropertyDescriptor(owner, name);
46 if (propDesc) {
47 ok(propDesc.enumerable,
48 `${prefix} object property ${name} should be enumerable`);
49 break;
51 owner = Object.getPrototypeOf(owner);
56 var m;
57 var testSet;
58 var testIndex;
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");
73 m.set("test2", 2);
74 is(m.size, 2, "SimpleMap: size should be 2");
75 testSet = [["test", 1], ["test2", 2]];
76 testIndex = 0;
77 m.forEach(function(v, k, o) {
78 "use strict";
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]);
82 testIndex += 1;
83 });
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");
89 var iterable = false;
90 for (let e of m) {
91 iterable = true;
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");
109 m.clear();
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");
119 m1 = m.add("test");
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");
123 m.add("test2");
124 is(m.size, 2, "SimpleSet: size should be 2");
125 testSet = ["test", "test2"];
126 testIndex = 0;
127 m.forEach(function(v, k, o) {
128 "use strict";
129 is(o, m, "SimpleSet: foreach obj is correct");
130 is(k, testSet[testIndex], "SimpleSet: foreach set key: " + k + " = " + testSet[testIndex]);
131 testIndex += 1;
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");
137 iterable = false;
138 for (let e of m) {
139 iterable = true;
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'");
156 m.clear();
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");
181 m.clearInternal();
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");
205 m.clearInternal();
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");
232 m.clearInternal();
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();
239 m.set("test", 1);
240 m.forEach(function(v, k, o) {
241 "use strict";
242 is(o, m, "ForEachThisOverride: foreach obj is correct");
243 is(this, 5, "ForEachThisOverride: 'this' value should be correct");
244 }, 5);
246 // Test defaulting arguments on maplike to undefined
247 info("MapArgsDefault: Testing maplike defaulting arguments to undefined");
248 m = new TestInterfaceMaplike();
249 m.set();
250 is(m.size, 1, "MapArgsDefault: should have 1 entry");
251 m.forEach(function(v, k) {
252 "use strict";
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");
258 m.delete();
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();
264 m.add();
265 is(m.size, 1, "SetArgsDefault: should have 1 entry");
266 m.forEach(function(v, k) {
267 "use strict";
268 is(typeof k, "string", "SetArgsDefault: key is a string");
269 is(k, "undefined", "SetArgsDefault: key is the string undefined");
271 m.delete();
272 is(m.size, 0, "SetArgsDefault: should have 0 entries");
274 SimpleTest.finish();
276 </script>
277 </body>
278 </html>